-
Notifications
You must be signed in to change notification settings - Fork 21
Open
Description
The scheme should make use of aggregating public keys, not using private keys, as one of the two parties having access to the other private keys is a security risk
I've tried to do the following
func AggregatePublicKeys(publicKeys [][]byte) ([33]byte, error) {
var aggregatePubKeyX, aggregatePubKeyY *big.Int
for _, pubKeyBytes := range publicKeys {
pubKeyX, pubKeyY := Unmarshal(Curve, pubKeyBytes)
if pubKeyX == nil || pubKeyY == nil {
return [33]byte{}, errors.New("invalid public key")
}
if aggregatePubKeyX == nil || aggregatePubKeyY == nil {
aggregatePubKeyX, aggregatePubKeyY = pubKeyX, pubKeyY
} else {
// Add the current public key to the aggregate public key.
aggregatePubKeyX, aggregatePubKeyY = Curve.Add(aggregatePubKeyX, aggregatePubKeyY, pubKeyX, pubKeyY)
}
}
if aggregatePubKeyX == nil || aggregatePubKeyY == nil {
return [33]byte{}, errors.New("no public keys provided")
}
aggregatedPubKeyBytes := Marshal(Curve, aggregatePubKeyX, aggregatePubKeyY)
var aggregatedPubKey [33]byte
copy(aggregatedPubKey[:], aggregatedPubKeyBytes)
return aggregatedPubKey, nil
}and this test passes:
func TestAggregatePublicKeys(t *testing.T) {
privKeyHex1 := "B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF"
privKeyHex2 := "C90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B14E5C7"
privKey1, _ := new(big.Int).SetString(privKeyHex1, 16)
privKey2, _ := new(big.Int).SetString(privKeyHex2, 16)
pubKey1X, pubKey1Y := Curve.ScalarBaseMult(privKey1.Bytes())
pubKey2X, pubKey2Y := Curve.ScalarBaseMult(privKey2.Bytes())
pubKeyBytes1 := Marshal(Curve, pubKey1X, pubKey1Y)
pubKeyBytes2 := Marshal(Curve, pubKey2X, pubKey2Y)
aggregatedPubKey, err := AggregatePublicKeys([][]byte{pubKeyBytes1, pubKeyBytes2})
if err != nil {
t.Fatalf("Failed to aggregate public keys: %v", err)
}
expectedAggregatedPubKeyHex := "03f0a6305d39a34582ba49a78bdf38ced935b3efce1e889d6820103665f35ee45b"
expectedAggregatedPubKeyBytes, err := hex.DecodeString(expectedAggregatedPubKeyHex)
if err != nil {
t.Fatalf("Failed to decode expected aggregated public key hex: %v", err)
}
aggregatedPubKeyHex := hex.EncodeToString(aggregatedPubKey[:])
if aggregatedPubKeyHex != expectedAggregatedPubKeyHex {
t.Errorf("Aggregated public key does not match the expected value.\nExpected: %s\nGot: %s", expectedAggregatedPubKeyHex, aggregatedPubKeyHex)
}
if hex.EncodeToString(expectedAggregatedPubKeyBytes) != aggregatedPubKeyHex {
t.Errorf("Aggregated public key bytes do not match the expected bytes.\nExpected: %x\nGot: %x", expectedAggregatedPubKeyBytes, aggregatedPubKey)
}
}but this test fails
func TestVerifyWithAggregatedPublicKey(t *testing.T) {
// Step 1: Aggregate public keys
privKeysHex := []string{
"B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF",
"C90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B14E5C7",
}
var publicKeys [][]byte
for _, hexKey := range privKeysHex {
privKey, ok := new(big.Int).SetString(hexKey, 16)
if !ok {
t.Fatalf("Failed to parse private key: %s", hexKey)
}
px, py := Curve.ScalarBaseMult(privKey.Bytes())
publicKeys = append(publicKeys, Marshal(Curve, px, py))
}
fmt.Println(publicKeys)
aggregatedPublicKey, err := AggregatePublicKeys(publicKeys)
if err != nil {
t.Fatalf("Failed to aggregate public keys: %v", err)
}
// Step 2: Sign a message using one of the private keys
message := [32]byte{ /* your message here, can be random */ }
privKeyBigInt, ok := new(big.Int).SetString(privKeysHex[0], 16)
if !ok {
t.Fatalf("Failed to parse private key: %s", privKeysHex[0])
}
signature, err := Sign(privKeyBigInt, message)
if err != nil {
t.Fatalf("Failed to sign message: %v", err)
}
// Step 3: Verify the signature against the aggregated public key
verified, err := Verify(aggregatedPublicKey, message, signature)
if err != nil {
t.Fatalf("Verification failed with error: %v", err)
}
if !verified {
t.Fatal("Failed to verify signature with aggregated public key")
}
}why does the AggregateSignatures function signature expect a set of private keys instead of public keys:
func AggregateSignatures(privateKeys []*big.Int, message [32]byte) ([64]byte, error) {Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels