Closed dominictarr closed 6 years ago
Currently I'm stuck on distributed key generation, so I don't think I can give a very satisfying answer yet. But after DKG we should have a 1) a group with a size of group_size
and a 2) threshold of size threshold_size
3) master public key for the group and each participant has an ID (just a int) and a corresponding public and private key (that is tied to its ID).
So to recap we have something like
{
groupPublicKey: <pub_key>
groupMembers [
[<id>, <pub_key>, <secret_key>], // pub_key & secret_key generated from DKG
[<id>, <pub_key>, <secret_key>],
...
]
}
Now the group members can create a signature share with the following.
const msg = 'hello mars!'
const sig = bls.signature()
bls.sign(sig, secret_key, msg)
const sigShare = bls.serailizeSignature(sig) // produces an int8Array containing 32-bytes
Its called a "share" because once we have threshold_size
signatures from unique group members on the same message we can recombine them and validate the message with groupPublicKey
.
const shares = [[<id>, <sig>]] // an array of the lenght threshold_size with signatures from group members produced by the above code and there corresponding id
const sigs = signatureShares.map(share => {
const sig = bls.signature()
bls.signatureDeserialize(sig, share[1])
return sig
})
const ids = signatureShares.map(share => share[0])
const sig = bls.signature()
bls.signatureRecover(sig, sigs, ids)
const valid = bls.verify(sig, groupPublicKey, 'hello mars!') // should be 1
Now I don't have all the pieces for DKG but if you don't mind a trusted party setting up the group use can do the following
// `ids` are an array of ints. And threshold is an Int that is less then ids.length
function createGroup (ids, threshold) {
const secretKey = [] //master sk
const publicKey = [] // master pk
const group = {
ids: {}
}
// generate the master sk and pk
for (let i = 0; i < threshold; i++) {
const sk = bls.secretKey()
bls.secretKeySetByCSPRNG(sk)
secretKey.push(sk)
const pk = bls.publicKey()
bls.getPublicKey(pk, sk)
publicKey.push(pk)
}
// generate the pk and sk for the group members
for (let i = 0; i < ids.length; i++) {
const index = ids[i].index
const id = bls.secretKey()
bls.idSetInt(id, index)
const sk = bls.secretKey()
bls.secretKeyShare(sk, secretKey, id)
const pk = bls.publicKey()
bls.publicKeyShare(pk, publicKey, id)
group.ids[index] = {
secretKey: Buffer.from(bls.secretKeySerialize(sk)).toString('hex'),
publicKey: Buffer.from(bls.publicKeySerialize(pk)).toString('hex')
}
}
group.publicKey = Buffer.from(bls.publicKeySerialize(publicKey[0])).toString('hex')
return group
}
moving to here https://github.com/wanderer/dkg
The current documentation gives a low level description of the signatures of the various methods, but I need a high level explaination of how shares are combined and what the properties are, The library this is based on https://github.com/herumi/bls also isn't any better and neither link to material that explains it. Do you know of a good place to learn more?