Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elliptic curve threshold cryptography in node

I'd like to implement something like the two-man rule using elliptic curve cryptography in javascript.

Edit: I'm essentially looking for something like Bitcoin multisig.

So I need to take combine two public keys to get a combined key that requires both private keys to produce a signature. See https://crypto.stackexchange.com/questions/25250/adding-two-public-keys.

How can I do this in node?

like image 465
Luke Burns Avatar asked Jul 04 '15 20:07

Luke Burns


People also ask

How the elliptic curve can be used for cryptography?

Introducing Elliptic Curve Cryptography ECC generates keys through the properties of the elliptic curve equation instead of the traditional method of generation as the product of very large prime numbers. The technology can be used in conjunction with most public key encryption methods, such as RSA, and Diffie-Hellman.

What is the minimum key size in elliptic curve cryptography ECC )?

It has been noted by the NSA that the encryption of a top-secret document by elliptic curve cryptography requires a key length of 384 bit. A key length of the same size by RSA would deliver no where near the same level of security.

What is Secp256k1?

Secp256k1 is the name of the elliptic curve used by Bitcoin to implement its public key cryptography. All points on this curve are valid Bitcoin public keys.

How do you find the 2P of an elliptic curve cryptography?

If x2 = x1 and y2 = −y1, that is P = (x1,y1) and Q = (x2,y2) = (x1,−y1) = −P, then P + Q = O. Therefore 2P = (x3,y3) = (7,12).


1 Answers

Since elliptic curve threshold cryptosystems have the property of adding keys, why not just do that?

I've attempted this using the elliptic module for node.js, just install it with npm and then try the following

var EC = require('elliptic').ec;
// we use the same preset of bitcoin, but should work with the other ones too
var ec = new EC('secp256k1');

// generate two (or more) starting keypairs
var key1 = ec.genKeyPair();
var key2 = ec.genKeyPair();

// sum the public... 
var sum = key1.getPublic().add(key2.getPublic());
// ...and private keys
var psum = key1.getPrivate().add(key2.getPrivate());

Since public keys are Point objects and private keys are BigNumber objects, you can just call the add() function on both of them. At this point, sum and psum hold your combined keys, but before using them to sign a message you'll need to create a KeyPair object (part of the elliptic module).

// generate two new random keypairs
var privateKeySum = ec.genKeyPair();
var publicKeySum = ec.genKeyPair();

// we don't care about their values
// so just import the sum of keys into them
privateKeySum._importPrivate(psum);
publicKeySum._importPublic(sum);

As you can see, to create a new keypair I just make new random ones and then use the _importPrivate() and _importPublic() functions to load the combined keys.

It's a bit hacky, I know, but it works.

A better solution would be to just export the KeyPair object from the module and create new ones with their constructor.

After this, just proceed as normal, like in the sample provided by the module's readme:

var msg = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
// Sign the message with our new combined private key
var signature = privateKeySum.sign(msg);

// Export DER encoded signature in Array
var derSign = signature.toDER();

// Verify signature using the combined public key, should return true
console.log(publicKeySum.verify(msg, derSign));

Using this, after the first generation, you can ask for the two (or more) public keys required to verify a message signature. If you treat the public keys as 'passwords', you can then check a signature against any message to verify that the two public keys are the original ones.

Also, this should work with multiple keys, but it will always require all of them to succeed.

like image 186
Sosdoc Avatar answered Sep 27 '22 23:09

Sosdoc