2015-07-04 15 views
11

Mi piacerebbe implementare qualcosa come lo two-man rule utilizzando la crittografia a curva ellittica in javascript.Crittografia della soglia della curva ellittica nel nodo

Edit: Sto essenzialmente cercando qualcosa come Bitcoin multisig.

Quindi ho bisogno di prendere unire due chiavi pubbliche per ottenere una chiave combinata che richiede che entrambe le chiavi private producano una firma. Vedi https://crypto.stackexchange.com/questions/25250/adding-two-public-keys.

Come posso fare questo nel nodo?

+2

Qualcosa come questo: https://github.com/wanderer/secp256k1-node ma completamente in JS senza la C? –

+0

Stai provando a farlo nel browser o con il nodo? – Breedly

+0

Cercando di farlo nel nodo. –

risposta

7

Poiché i crittosistemi a soglia di curva ellittica hanno la proprietà di aggiungere chiavi, perché non farlo?

ho tentato questa operazione utilizzando il elliptic module per node.js, basta installarlo con NPM e quindi provare il seguente

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()); 

Poiché le chiavi pubbliche sono Point oggetti e le chiavi private sono BigNumber oggetti, si può solo chiamare la funzione add() su entrambi. A questo punto, sum e psum tenere le chiavi combinate, ma prima di utilizzarle per firmare un messaggio è necessario creare un oggetto KeyPair (parte del modulo ellittico).

// 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); 

Come si può vedere, per creare una nuova coppia di chiavi ho solo fare nuove quelli casuali e quindi utilizzare il _importPrivate() e _importPublic() funzioni per caricare le chiavi combinate.

È un po 'hacky, lo so, ma funziona.

Una soluzione migliore sarebbe esportare semplicemente l'oggetto KeyPair dal modulo e crearne di nuovi con il proprio costruttore.

Dopo questo, basta procedere come normale, come nel campione fornito dal readme del modulo:

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)); 

Usando questo, dopo la prima generazione, si può chiedere per i due (o più) chiavi pubbliche necessarie per verificare una firma del messaggio. Se si trattano le chiavi pubbliche come "password", è possibile controllare una firma con qualsiasi messaggio per verificare che le due chiavi pubbliche siano originali.

Inoltre, questo dovrebbe funzionare con più chiavi, ma richiederà sempre tutte le di esse per riuscire.