sign function complete
This commit is contained in:
parent
34c9e94365
commit
9481074f0c
3
.gitignore
vendored
3
.gitignore
vendored
@ -2,4 +2,5 @@ examples.mk
|
|||||||
json-rpc/
|
json-rpc/
|
||||||
supernode/websocket_chat
|
supernode/websocket_chat
|
||||||
supernode/floaddress.org.html
|
supernode/floaddress.org.html
|
||||||
supernode/Makefile
|
supernode/Makefile
|
||||||
|
list.txt
|
||||||
196
supernode/ecdsa.html
Normal file
196
supernode/ecdsa.html
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>WebCrypto API Demo: ECDSA Generate Keys Sign Verify Message </title>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var privateKey;
|
||||||
|
var publicKey;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var iv;
|
||||||
|
|
||||||
|
|
||||||
|
function asciiToUint8Array(str) {
|
||||||
|
var chars = [];
|
||||||
|
for (var i = 0; i < str.length; ++i)
|
||||||
|
chars.push(str.charCodeAt(i));
|
||||||
|
return new Uint8Array(chars);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ECDSA_Sign() {
|
||||||
|
|
||||||
|
var cryptoObj = window.crypto || window.msCrypto;
|
||||||
|
|
||||||
|
if(!cryptoObj)
|
||||||
|
{
|
||||||
|
alert("Crypto API is not supported by the Browser");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var plainText = document.getElementById("plainText").value;
|
||||||
|
var curve = document.getElementById("curve").value;
|
||||||
|
|
||||||
|
window.crypto.subtle.generateKey({
|
||||||
|
name: "ECDSA",
|
||||||
|
namedCurve: curve, //can be "P-256", "P-384", or "P-521"
|
||||||
|
},
|
||||||
|
true, //whether the key is extractable (i.e. can be used in exportKey)
|
||||||
|
["sign", "verify"] //can be any combination of "sign" and "verify"
|
||||||
|
)
|
||||||
|
.then(function(key) {
|
||||||
|
|
||||||
|
publicKey = key.publicKey;
|
||||||
|
privateKey = key.privateKey;
|
||||||
|
// For Demo Purpos Only Exported in JWK format
|
||||||
|
window.crypto.subtle.exportKey("jwk", key.publicKey).then(
|
||||||
|
function(keydata) {
|
||||||
|
publicKeyhold = keydata;
|
||||||
|
publicKeyJson = JSON.stringify(publicKeyhold);
|
||||||
|
document.getElementById("ecdsapublic").value = publicKeyJson;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
window.crypto.subtle.exportKey("jwk", key.privateKey).then(
|
||||||
|
function(keydata) {
|
||||||
|
privateKeyhold = keydata;
|
||||||
|
privateKeyJson = JSON.stringify(privateKeyhold);
|
||||||
|
document.getElementById("ecdsaprivate").value = privateKeyJson;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
window.crypto.subtle.sign({
|
||||||
|
name: "ECDSA",
|
||||||
|
hash: {
|
||||||
|
name: "SHA-256"
|
||||||
|
}, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
|
||||||
|
},
|
||||||
|
privateKey, //from generateKey or importKey above
|
||||||
|
asciiToUint8Array(plainText) //ArrayBuffer of data you want to sign
|
||||||
|
)
|
||||||
|
.then(function(signature) {
|
||||||
|
//returns an ArrayBuffer containing the signature
|
||||||
|
document.getElementById("cipherText").value = bytesToHexString(signature);
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function ECDSA_Verify() {
|
||||||
|
|
||||||
|
var cryptoObj = window.crypto || window.msCrypto;
|
||||||
|
|
||||||
|
if(!cryptoObj)
|
||||||
|
{
|
||||||
|
alert("Crypto API is not supported by the Browser");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var cipherText = document.getElementById("cipherText").value;
|
||||||
|
var plainText = document.getElementById("plainText").value;
|
||||||
|
|
||||||
|
if(!publicKey)
|
||||||
|
{
|
||||||
|
alert("Generate ECDSA Keys First")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.crypto.subtle.verify({
|
||||||
|
name: "ECDSA",
|
||||||
|
hash: {name: "SHA-256"}, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
|
||||||
|
},
|
||||||
|
publicKey, //from generateKey or importKey above
|
||||||
|
hexStringToUint8Array(cipherText), //ArrayBuffer of the data
|
||||||
|
asciiToUint8Array(plainText)
|
||||||
|
)
|
||||||
|
.then(function(decrypted) {
|
||||||
|
alert("Verified " + decrypted);
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function bytesToASCIIString(bytes) {
|
||||||
|
return String.fromCharCode.apply(null, new Uint8Array(bytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
function bytesToHexString(bytes) {
|
||||||
|
if (!bytes)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
bytes = new Uint8Array(bytes);
|
||||||
|
var hexBytes = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < bytes.length; ++i) {
|
||||||
|
var byteString = bytes[i].toString(16);
|
||||||
|
if (byteString.length < 2)
|
||||||
|
byteString = "0" + byteString;
|
||||||
|
hexBytes.push(byteString);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hexBytes.join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
function hexStringToUint8Array(hexString) {
|
||||||
|
if (hexString.length % 2 != 0)
|
||||||
|
throw "Invalid hexString";
|
||||||
|
var arrayBuffer = new Uint8Array(hexString.length / 2);
|
||||||
|
|
||||||
|
for (var i = 0; i < hexString.length; i += 2) {
|
||||||
|
var byteValue = parseInt(hexString.substr(i, 2), 16);
|
||||||
|
if (byteValue == NaN)
|
||||||
|
throw "Invalid hexString";
|
||||||
|
arrayBuffer[i / 2] = byteValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return arrayBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function failAndLog(error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Generate ECDSA Public Private Keys and perform Sign and Verify Message </h1>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
|
||||||
|
Named Curve <select name="curve" id="curve">
|
||||||
|
<option value="P-256">P-256</option>
|
||||||
|
<option value="P-384">P-384</option>
|
||||||
|
<option value="P-521">P-521</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
Input Text to Signed<input type="text" name="plainText" value="Hello 8gwifi" id="plainText">
|
||||||
|
|
||||||
|
<button type="button" onclick="ECDSA_Sign()">Generate ECDSA keys and Perform Sign </button>
|
||||||
|
|
||||||
|
<button type="button" onclick="ECDSA_Verify()">Verify ECDSA Signature </button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
Signature Output (Hex) <input type="text" size="30" name="cipherText" id="cipherText" readonly="true"><br>
|
||||||
|
ECDSA Public Key (JWK) : <textarea name="ecdsapublic" id="ecdsapublic" cols="30" rows="10"> </textarea><br>
|
||||||
|
ECDSA Private Key (JWK): <textarea name="ecdsaprivate" id="ecdsaprivate" cols="30" rows="10"></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<br> Thanks for downloading the code, if you like it Support <a href="8gwifi.org">8gwifi.org </a> By purchasing The Modern Cryptography Cookbook
|
||||||
|
<iframe width='160' height='400' src='https://leanpub.com/crypto/embed' frameborder='0' allowtransparency='true'></iframe>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -38,8 +38,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
if (typeof Crypto == "undefined" || !Crypto.util) {
|
if (typeof Crypto == "undefined" || !Crypto.util) {
|
||||||
(function () {
|
(function () {
|
||||||
@ -5671,7 +5669,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|||||||
</script>
|
</script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
//https://raw.github.com/bitcoinjs/bitcoinjs-lib/e90780d3d3b8fc0d027d2bcb38b80479902f223e/src/ecdsa.js
|
//https://raw.github.com/bitcoinjs/bitcoinjs-lib/e90780d3d3b8fc0d027d2bcb38b80479902f223e/src/ecdsa.js
|
||||||
Bitcoin.ECDSA = (function () {
|
Bitcoin.ECDSA = (function (ec) {
|
||||||
var ecparams = EllipticCurve.getSECCurveByName("secp256k1");
|
var ecparams = EllipticCurve.getSECCurveByName("secp256k1");
|
||||||
var rng = new SecureRandom();
|
var rng = new SecureRandom();
|
||||||
|
|
||||||
@ -5719,6 +5717,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|||||||
var G = ecparams.getG();
|
var G = ecparams.getG();
|
||||||
var Q = G.multiply(k);
|
var Q = G.multiply(k);
|
||||||
var r = Q.getX().toBigInteger().mod(n);
|
var r = Q.getX().toBigInteger().mod(n);
|
||||||
|
|
||||||
} while (r.compareTo(BigInteger.ZERO) <= 0);
|
} while (r.compareTo(BigInteger.ZERO) <= 0);
|
||||||
|
|
||||||
var s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n);
|
var s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n);
|
||||||
@ -5738,17 +5737,22 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|||||||
} else {
|
} else {
|
||||||
throw "Invalid value for signature";
|
throw "Invalid value for signature";
|
||||||
}
|
}
|
||||||
|
console.log(hash);
|
||||||
|
console.log(sig);
|
||||||
|
console.log("pubkey instanceof ec.PointFp: ", pubkey instanceof ec.PointFp);
|
||||||
|
console.log("Bitcoin.Util.isArray(pubkey): ", Bitcoin.Util.isArray(pubkey));
|
||||||
|
|
||||||
var Q;
|
var Q;
|
||||||
if (pubkey instanceof ec.PointFp) {
|
if (pubkey instanceof ec.PointFp) {
|
||||||
Q = pubkey;
|
Q = pubkey;
|
||||||
} else if (Bitcoin.Util.isArray(pubkey)) {
|
} else
|
||||||
|
if (Bitcoin.Util.isArray(pubkey)) {
|
||||||
Q = EllipticCurve.PointFp.decodeFrom(ecparams.getCurve(), pubkey);
|
Q = EllipticCurve.PointFp.decodeFrom(ecparams.getCurve(), pubkey);
|
||||||
} else {
|
} else {
|
||||||
throw "Invalid format for pubkey value, must be byte array or ec.PointFp";
|
throw "Invalid format for pubkey value, must be byte array or ec.PointFp";
|
||||||
}
|
}
|
||||||
var e = BigInteger.fromByteArrayUnsigned(hash);
|
var e = BigInteger.fromByteArrayUnsigned(hash);
|
||||||
|
|
||||||
return ECDSA.verifyRaw(e, r, s, Q);
|
return ECDSA.verifyRaw(e, r, s, Q);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -5777,6 +5781,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|||||||
|
|
||||||
var v = point.getX().toBigInteger().mod(n);
|
var v = point.getX().toBigInteger().mod(n);
|
||||||
|
|
||||||
|
console.log(v);
|
||||||
|
console.log(r);
|
||||||
|
|
||||||
return v.equals(r);
|
return v.equals(r);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -5959,7 +5966,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|||||||
};
|
};
|
||||||
|
|
||||||
return ECDSA;
|
return ECDSA;
|
||||||
})();
|
})(window.EllipticCurve);
|
||||||
</script>
|
</script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
Bitcoin.KeyPool = (function () {
|
Bitcoin.KeyPool = (function () {
|
||||||
@ -7648,6 +7655,62 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|||||||
})(ninja.wallets, ninja.qrCode);
|
})(ninja.wallets, ninja.qrCode);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function (wallets) {
|
||||||
|
|
||||||
|
var signing = wallets.flowallet = {
|
||||||
|
bigInt: function (data) {
|
||||||
|
var BI = new BigInteger(data);
|
||||||
|
return BI;
|
||||||
|
},
|
||||||
|
generateFloKeys: function () {
|
||||||
|
var key = new Bitcoin.ECKey(false);
|
||||||
|
key.setCompressed(true);
|
||||||
|
var bitcoinAddress = key.getBitcoinAddress();
|
||||||
|
var privateKeyWif = key.getBitcoinWalletImportFormat();
|
||||||
|
var privateKey = key.getBitcoinHexFormat();
|
||||||
|
var publicKey = key.getPubKeyHex();
|
||||||
|
var publicKeyECPoint = key.getPubPoint(); // Return public point as ECPoint object.
|
||||||
|
console.log("bitcoinAddress", bitcoinAddress);
|
||||||
|
console.log("privateKeyWif", privateKeyWif);
|
||||||
|
console.log("publicKey", publicKey);
|
||||||
|
|
||||||
|
var ms = "hello";
|
||||||
|
var signn = this.sign(ms, privateKeyWif);
|
||||||
|
|
||||||
|
var veri = this.verify(ms, signn, publicKey);
|
||||||
|
console.log(veri);
|
||||||
|
|
||||||
|
},
|
||||||
|
sign: function (msg, privateKey) {
|
||||||
|
var msgHash = Crypto.SHA256(msg);
|
||||||
|
var msgHashBI = this.bigInt(msgHash);
|
||||||
|
var privateKeyHashBI = this.bigInt(privateKey);
|
||||||
|
var signature = new Bitcoin.ECDSA.sign(msgHashBI, privateKeyHashBI);
|
||||||
|
|
||||||
|
//return signature;
|
||||||
|
console.log(Crypto.util.bytesToHex(signature));
|
||||||
|
|
||||||
|
return Crypto.util.bytesToHex(signature);
|
||||||
|
},
|
||||||
|
verify: function (msg, signature, publicKey) {
|
||||||
|
var msgHash = Crypto.SHA256(msg);
|
||||||
|
var msgHashBI = this.bigInt(msgHash);
|
||||||
|
//var msgHashBI = Crypto.util.hexToBytes(msgHash);
|
||||||
|
|
||||||
|
var signatureBI = Crypto.util.hexToBytes(signature);
|
||||||
|
//var signatureBI = this.bigInt(signature);
|
||||||
|
//console.log(signatureBI);
|
||||||
|
|
||||||
|
//var publicKeyBI = this.bigInt(publicKey);
|
||||||
|
var publicKeyBI = Crypto.util.hexToBytes(publicKey);
|
||||||
|
|
||||||
|
var verification = new Bitcoin.ECDSA.verify(msgHashBI, signatureBI, publicKeyBI);
|
||||||
|
return verification;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})(ninja.wallets)
|
||||||
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user