func benchGenSigOpenSSL(nkeys int) []byte { suite := openssl.NewAES128SHA256P256() rand := suite.Cipher([]byte("example")) return Sign(suite, rand, benchMessage, Set(benchPubOpenSSL[:nkeys]), nil, 0, benchPriOpenSSL) }
// This code shows how to create and verify Or-predicate proofs, // such as the one above. // In this case, we know a secret x such that X=x*B, // but we don't know a secret y such that Y=y*B, // because we simply pick Y as a random point // instead of generating it by scalar multiplication. // (And if the group is cryptographically secure // we won't find be able to find such a y.) func ExampleOr_2() { // Create an Or predicate. pred := Or(Rep("X", "x", "B"), Rep("Y", "y", "B")) fmt.Println("Predicate: " + pred.String()) // Crypto setup suite := openssl.NewAES128SHA256P256() rand := suite.Cipher([]byte("example")) B := suite.Point().Base() // standard base point // Create a public/private keypair (X,x) and a random point Y x := suite.Secret().Pick(rand) // create a private key x X := suite.Point().Mul(nil, x) // corresponding public key X Y, _ := suite.Point().Pick(nil, rand) // pick a random point Y // We'll need to tell the prover which Or clause is actually true. // In this case clause 0, the first sub-predicate, is true: // i.e., we know a secret x such that X=x*B. choice := make(map[Predicate]int) choice[pred] = 0 // Generate a proof that we know the discrete logarithm of X or Y. sval := map[string]abstract.Secret{"x": x} pval := map[string]abstract.Point{"B": B, "X": X, "Y": Y} prover := pred.Prover(suite, sval, pval, choice) proof, _ := HashProve(suite, "TEST", rand, prover) fmt.Print("Proof:\n" + hex.Dump(proof)) // Verify this knowledge proof. // The verifier doesn't need the secret values or choice map, of course. verifier := pred.Verifier(suite, pval) err := HashVerify(suite, "TEST", verifier, proof) if err != nil { panic("proof failed to verify!") } fmt.Println("Proof verified.") // Output: // Predicate: X=x*B || Y=y*B // Proof: // 00000000 02 af 84 ed e5 86 04 cf 81 e4 18 17 84 0c 39 ab |..............9.| // 00000010 fe 5c bc cc 00 85 e0 a2 ee aa d5 22 18 dd c4 a1 |.\........."....| // 00000020 5b 03 df 9c 59 21 0e 1c 44 99 23 a1 54 92 21 c9 |[...Y!..D.#.T.!.| // 00000030 d6 b3 84 85 ad 87 dd a3 64 c0 b9 eb 4d 92 5b cb |........d...M.[.| // 00000040 c6 4f e7 67 95 36 6a e4 e7 ca b5 14 b7 99 16 60 |.O.g.6j........`| // 00000050 71 91 ad b0 f1 86 43 df 6a 45 1f cb a2 93 7e b3 |q.....C.jE....~.| // 00000060 b5 7b 32 17 7d 53 c5 e4 48 79 49 b2 3e 1e e2 62 |.{2.}S..HyI.>..b| // 00000070 39 08 13 d5 2e f8 c5 e9 c1 28 09 91 7a 95 c9 12 |9........(..z...| // 00000080 17 85 f5 eb 2d 8e 6b 37 3a b5 ff 45 25 e7 0c aa |....-.k7:..E%...| // 00000090 94 43 cf 67 52 2e 1d 2c 1b a4 c0 ca 96 d6 03 08 |.C.gR..,........| // 000000a0 c0 0d 93 8b c6 f6 34 12 83 a0 32 2e 82 2c 4b fb |......4...2..,K.| // 000000b0 b3 0c a1 4b a5 e3 27 43 b6 2f ed fa ca 4f 93 83 |...K..'C./...O..| // 000000c0 fd 56 |.V| // Proof verified. }
func TestRep(t *testing.T) { suite := openssl.NewAES128SHA256P256() rand := suite.Cipher(abstract.RandomKey) x := suite.Secret().Pick(rand) y := suite.Secret().Pick(rand) B := suite.Point().Base() X := suite.Point().Mul(nil, x) Y := suite.Point().Mul(X, y) R := suite.Point().Add(X, Y) choice := make(map[Predicate]int) // Simple single-secret predicate: prove X=x*B log := Rep("X", "x", "B") // Two-secret representation: prove R=x*B+y*X rep := Rep("R", "x", "B", "y", "X") // Make an and-predicate and := And(log, rep) andx := And(and) // Make up a couple incorrect facts falseLog := Rep("Y", "x", "B") falseRep := Rep("R", "x", "B", "y", "B") falseAnd := And(falseLog, falseRep) or1 := Or(falseAnd, andx) choice[or1] = 1 or1x := Or(or1) // test trivial case choice[or1x] = 0 or2a := Rep("B", "y", "X") or2b := Rep("R", "x", "R") or2 := Or(or2a, or2b) or2x := Or(or2) // test trivial case pred := Or(or1x, or2x) choice[pred] = 0 sval := map[string]abstract.Secret{"x": x, "y": y} pval := map[string]abstract.Point{"B": B, "X": X, "Y": Y, "R": R} prover := pred.Prover(suite, sval, pval, choice) proof, err := HashProve(suite, "TEST", rand, prover) if err != nil { panic("prover: " + err.Error()) } verifier := pred.Verifier(suite, pval) if err := HashVerify(suite, "TEST", verifier, proof); err != nil { panic("verify: " + err.Error()) } }
// This example demonstrates how to create unlinkable anonymity-set signatures, // and to verify them, // using a small anonymity set containing three public keys. func ExampleSign_anonSet() { // Crypto setup suite := openssl.NewAES128SHA256P256() rand := suite.Cipher([]byte("example")) // Create an anonymity set of random "public keys" X := make([]abstract.Point, 3) for i := range X { // pick random points X[i], _ = suite.Point().Pick(nil, rand) } // Make just one of them an actual public/private keypair (X[mine],x) mine := 1 // only the signer knows this x := suite.Secret().Pick(rand) // create a private key x X[mine] = suite.Point().Mul(nil, x) // corresponding public key X // Generate the signature M := []byte("Hello World!") // message we want to sign sig := Sign(suite, rand, M, Set(X), nil, mine, x) fmt.Print("Signature:\n" + hex.Dump(sig)) // Verify the signature against the correct message tag, err := Verify(suite, M, Set(X), nil, sig) if err != nil { panic(err.Error()) } if tag == nil || len(tag) != 0 { panic("Verify returned wrong tag") } fmt.Println("Signature verified against correct message.") // Verify the signature against the wrong message BAD := []byte("Goodbye world!") tag, err = Verify(suite, BAD, Set(X), nil, sig) if err == nil || tag != nil { panic("Signature verified against wrong message!?") } fmt.Println("Verifying against wrong message: " + err.Error()) // Output: // Signature: // 00000000 05 e5 e3 f4 80 22 d8 38 03 63 e6 9d b5 2c 51 28 |.....".8.c...,Q(| // 00000010 7c f1 78 cd 7d f2 0e dd a0 63 58 04 d7 79 ce 03 ||.x.}....cX..y..| // 00000020 56 b2 b5 3a e1 c8 8c f7 29 8a 13 75 59 98 ea ce |V..:....)..uY...| // 00000030 f4 6d d5 d0 62 85 51 8e fe d9 4a 02 1f 35 03 33 |.m..b.Q...J..5.3| // 00000040 bf 19 a6 0e b2 47 8d 8e 91 b1 a7 70 5c 62 6d d9 |.....G.....p\bm.| // 00000050 70 2a 39 f0 a0 60 59 c2 4e 76 2b d1 0e 06 29 2d |p*9..`Y.Nv+...)-| // 00000060 71 eb 40 46 de 61 2f 08 8d 9a 04 09 d7 a1 62 83 |[email protected]/.......b.| // 00000070 48 e3 cc 09 af 64 26 df df da d6 51 62 5d e6 2b |H....d&....Qb].+| // Signature verified against correct message. // Verifying against wrong message: invalid signature }
func ExampleEncrypt_anonSet() { // Crypto setup suite := openssl.NewAES128SHA256P256() rand := suite.Cipher([]byte("example")) // Create an anonymity set of random "public keys" X := make([]abstract.Point, 3) for i := range X { // pick random points X[i], _ = suite.Point().Pick(nil, rand) } // Make just one of them an actual public/private keypair (X[mine],x) mine := 1 // only the signer knows this x := suite.Secret().Pick(rand) // create a private key x X[mine] = suite.Point().Mul(nil, x) // corresponding public key X // Encrypt a message with all the public keys M := []byte("Hello World!") // message to encrypt C := Encrypt(suite, rand, M, Set(X), false) fmt.Printf("Encryption of '%s':\n%s", string(M), hex.Dump(C)) // Decrypt the ciphertext with the known private key MM, err := Decrypt(suite, C, Set(X), mine, x, false) if err != nil { panic(err.Error()) } if !bytes.Equal(M, MM) { panic("Decryption failed to reproduce message") } fmt.Printf("Decrypted: '%s'\n", string(MM)) // Output: // Encryption of 'Hello World!': // 00000000 02 c2 6c b8 1b 87 94 1d 71 c8 50 63 75 e1 80 5e |..l.....q.Pcu..^| // 00000010 b2 b8 1a d6 10 be 1a c6 35 bf b9 c0 cb af 67 d0 |........5.....g.| // 00000020 c1 38 04 f2 7e 70 c0 0e ce 2a 3e 8d a4 1a 8f d8 |.8..~p...*>.....| // 00000030 c6 ca 2d 81 2a 50 d0 4e 96 74 2a 8b 44 22 12 5f |..-.*P.N.t*.D"._| // 00000040 57 73 d1 1f a3 a9 21 96 2e e3 bd 77 bf 3b 3f a7 |Ws....!....w.;?.| // 00000050 b7 aa 91 37 7d d6 12 c6 73 db 9f 01 fd b3 f6 b6 |...7}...s.......| // 00000060 82 cf 0d e1 5c 57 ac 8e 82 72 20 06 af 70 90 15 |....\W...r ..p..| // 00000070 cb 5c f5 87 8d 39 3a 29 66 8e df 62 3d b0 ba fa |.\...9:)f..b=...| // 00000080 3f 38 83 eb 92 62 fd 33 cb b0 76 ae e1 af 60 f3 |?8...b.3..v...`.| // 00000090 7b ba 1d ef b0 2a 7a 19 a5 92 23 fa d3 |{....*z...#..| // Decrypted: 'Hello World!' }
// This example demonstrates signing and signature verification // using a trivial "anonymity set" of size 1, i.e., no anonymity. // In this special case the signing scheme devolves to // producing traditional ElGamal signatures: // the resulting signatures are exactly the same length // and represent essentially the same computational cost. func ExampleSign_1() { // Crypto setup suite := openssl.NewAES128SHA256P256() rand := suite.Cipher([]byte("example")) // Create a public/private keypair (X[mine],x) X := make([]abstract.Point, 1) mine := 0 // which public key is mine x := suite.Secret().Pick(rand) // create a private key x X[mine] = suite.Point().Mul(nil, x) // corresponding public key X // Generate the signature M := []byte("Hello World!") // message we want to sign sig := Sign(suite, rand, M, Set(X), nil, mine, x) fmt.Print("Signature:\n" + hex.Dump(sig)) // Verify the signature against the correct message tag, err := Verify(suite, M, Set(X), nil, sig) if err != nil { panic(err.Error()) } if tag == nil || len(tag) != 0 { panic("Verify returned wrong tag") } fmt.Println("Signature verified against correct message.") // Verify the signature against the wrong message BAD := []byte("Goodbye world!") tag, err = Verify(suite, BAD, Set(X), nil, sig) if err == nil || tag != nil { panic("Signature verified against wrong message!?") } fmt.Println("Verifying against wrong message: " + err.Error()) // Output: // Signature: // 00000000 ca e3 63 fd 0f a9 25 bd f0 c6 f4 e4 93 3a 3d c0 |..c...%......:=.| // 00000010 be 2d ee d1 7f 78 b5 d4 30 00 05 fa 2d ab f3 08 |.-...x..0...-...| // 00000020 ac 50 83 66 b9 9f 55 f4 79 48 28 66 cc 25 fb 16 |.P.f..U.yH(f.%..| // 00000030 60 d5 0f 88 d6 8d af 97 24 5d 00 ec de 2c 9b ed |`.......$]...,..| // Signature verified against correct message. // Verifying against wrong message: invalid signature }
// This example shows how to build classic ElGamal-style digital signatures // using the Camenisch/Stadler proof framework and HashProver. func ExampleHashProve_1() { // Crypto setup suite := openssl.NewAES128SHA256P256() rand := suite.Cipher([]byte("example")) B := suite.Point().Base() // standard base point // Create a public/private keypair (X,x) x := suite.Secret().Pick(rand) // create a private key x X := suite.Point().Mul(nil, x) // corresponding public key X // Generate a proof that we know the discrete logarithm of X. M := "Hello World!" // message we want to sign rep := Rep("X", "x", "B") sec := map[string]abstract.Secret{"x": x} pub := map[string]abstract.Point{"B": B, "X": X} prover := rep.Prover(suite, sec, pub, nil) proof, _ := HashProve(suite, M, rand, prover) fmt.Print("Signature:\n" + hex.Dump(proof)) // Verify the signature against the correct message M. verifier := rep.Verifier(suite, pub) err := HashVerify(suite, M, verifier, proof) if err != nil { panic("signature failed to verify!") } fmt.Println("Signature verified against correct message M.") // Now verify the signature against the WRONG message. BAD := "Goodbye World!" verifier = rep.Verifier(suite, pub) err = HashVerify(suite, BAD, verifier, proof) fmt.Println("Signature verify against wrong message: " + err.Error()) // Output: // Signature: // 00000000 02 23 62 b1 f9 cb f4 a2 6d 7f 3e 69 cb b6 77 ab |.#b.....m.>i..w.| // 00000010 90 fc 7c db a0 c6 e8 12 f2 0a d4 40 a4 b6 c4 de |..|........@....| // 00000020 9e ac 50 83 66 b9 9f 55 f4 79 48 28 66 cc 25 fb |..P.f..U.yH(f.%.| // 00000030 16 60 d5 0f 88 d6 8d af 97 24 5d 00 ec de 2c 9b |.`.......$]...,.| // 00000040 ed |.| // Signature verified against correct message M. // Signature verify against wrong message: invalid proof: commit mismatch }
// This example shows how to generate and verify noninteractive proofs // of the statement in the example above, i.e., // a proof of ownership of public key X. func ExampleRep_2() { pred := Rep("X", "x", "B") fmt.Println(pred.String()) // Crypto setup suite := openssl.NewAES128SHA256P256() rand := suite.Cipher([]byte("example")) B := suite.Point().Base() // standard base point // Create a public/private keypair (X,x) x := suite.Secret().Pick(rand) // create a private key x X := suite.Point().Mul(nil, x) // corresponding public key X // Generate a proof that we know the discrete logarithm of X. sval := map[string]abstract.Secret{"x": x} pval := map[string]abstract.Point{"B": B, "X": X} prover := pred.Prover(suite, sval, pval, nil) proof, _ := HashProve(suite, "TEST", rand, prover) fmt.Print("Proof:\n" + hex.Dump(proof)) // Verify this knowledge proof. verifier := pred.Verifier(suite, pval) err := HashVerify(suite, "TEST", verifier, proof) if err != nil { panic("proof failed to verify!") } fmt.Println("Proof verified.") // Output: // X=x*B // Proof: // 00000000 02 23 62 b1 f9 cb f4 a2 6d 7f 3e 69 cb b6 77 ab |.#b.....m.>i..w.| // 00000010 90 fc 7c db a0 c6 e8 12 f2 0a d4 40 a4 b6 c4 de |..|........@....| // 00000020 9e 53 67 12 c7 31 0a 92 ed 76 c4 4d 2c 4b fc 2c |.Sg..1...v.M,K.,| // 00000030 56 db 2d 8a 84 ec 5d e5 31 17 80 76 a8 ea 46 04 |V.-...].1..v..F.| // 00000040 c8 |.| // Proof verified. }
func ExampleEncrypt_1() { // Crypto setup suite := openssl.NewAES128SHA256P256() rand := suite.Cipher([]byte("example")) // Create a public/private keypair (X[mine],x) X := make([]abstract.Point, 1) mine := 0 // which public key is mine x := suite.Secret().Pick(rand) // create a private key x X[mine] = suite.Point().Mul(nil, x) // corresponding public key X // Encrypt a message with the public key M := []byte("Hello World!") // message to encrypt C := Encrypt(suite, rand, M, Set(X), false) fmt.Printf("Encryption of '%s':\n%s", string(M), hex.Dump(C)) // Decrypt the ciphertext with the private key MM, err := Decrypt(suite, C, Set(X), mine, x, false) if err != nil { panic(err.Error()) } if !bytes.Equal(M, MM) { panic("Decryption failed to reproduce message") } fmt.Printf("Decrypted: '%s'\n", string(MM)) // Output: // Encryption of 'Hello World!': // 00000000 02 23 62 b1 f9 cb f4 a2 6d 7f 3e 69 cb b6 77 ab |.#b.....m.>i..w.| // 00000010 90 fc 7c db a0 c6 e8 12 f2 0a d4 40 a4 b6 c4 de |..|........@....| // 00000020 9e 5a 8a 1d 5b e4 96 f7 a9 cb 78 4e 8e ee 23 6b |.Z..[.....xN..#k| // 00000030 f3 5c fc 85 95 59 b0 81 72 bc e2 7b bf d5 1f c1 |.\...Y..r..{....| // 00000040 5f d2 08 9a e5 f0 d9 3c 6b 0d 83 35 6d 15 b1 93 |_......<k..5m...| // 00000050 af 1d a2 17 df db 3c 2b 89 32 1b 62 1b |......<+.2.b.| // Decrypted: 'Hello World!' }
func BenchmarkVerify100OpenSSL(b *testing.B) { benchVerify(openssl.NewAES128SHA256P256(), benchPubOpenSSL[:100], benchSig100OpenSSL, b.N) }
func BenchmarkSign100OpenSSL(b *testing.B) { benchSign(openssl.NewAES128SHA256P256(), benchPubOpenSSL[:100], benchPriOpenSSL, b.N) }
func benchGenKeysOpenSSL(nkeys int) ([]abstract.Point, abstract.Secret) { return benchGenKeys(openssl.NewAES128SHA256P256(), nkeys) }
// This example demonstrates the creation of linkable anonymity set signatures, // and verification, using an anonymity set containing three public keys. // We produce four signatures, two from each of two private key-holders, // demonstrating how the resulting verifiable tags distinguish // signatures by the same key-holder from signatures by different key-holders. func ExampleSign_linkable() { // Crypto setup suite := openssl.NewAES128SHA256P256() rand := suite.Cipher([]byte("example")) // Create an anonymity set of random "public keys" X := make([]abstract.Point, 3) for i := range X { // pick random points X[i], _ = suite.Point().Pick(nil, rand) } // Make two actual public/private keypairs (X[mine],x) mine1 := 1 // only the signer knows this mine2 := 2 x1 := suite.Secret().Pick(rand) // create a private key x x2 := suite.Secret().Pick(rand) X[mine1] = suite.Point().Mul(nil, x1) // corresponding public key X X[mine2] = suite.Point().Mul(nil, x2) // Generate two signatures using x1 and two using x2 M := []byte("Hello World!") // message we want to sign S := []byte("My Linkage Scope") // scope for linkage tags var sig [4][]byte sig[0] = Sign(suite, rand, M, Set(X), S, mine1, x1) sig[1] = Sign(suite, rand, M, Set(X), S, mine1, x1) sig[2] = Sign(suite, rand, M, Set(X), S, mine2, x2) sig[3] = Sign(suite, rand, M, Set(X), S, mine2, x2) for i := range sig { fmt.Printf("Signature %d:\n%s", i, hex.Dump(sig[i])) } // Verify the signatures against the correct message var tag [4][]byte for i := range sig { goodtag, err := Verify(suite, M, Set(X), S, sig[i]) if err != nil { panic(err.Error()) } tag[i] = goodtag if tag[i] == nil || len(tag[i]) != suite.PointLen() { panic("Verify returned invalid tag") } fmt.Printf("Sig%d tag: %s\n", i, hex.EncodeToString(tag[i])) // Verify the signature against the wrong message BAD := []byte("Goodbye world!") badtag, err := Verify(suite, BAD, Set(X), S, sig[i]) if err == nil || badtag != nil { panic("Signature verified against wrong message!?") } } if !bytes.Equal(tag[0], tag[1]) || !bytes.Equal(tag[2], tag[3]) || bytes.Equal(tag[0], tag[2]) { panic("tags aren't coming out right!") } // Output: // Signature 0: // 00000000 7f 0d 4b b1 47 ca 5e f5 4c 2f b3 71 44 1a 08 04 |..K.G.^.L/.qD...| // 00000010 02 d2 67 43 3b 58 19 69 56 44 73 b3 49 bd 19 ce |..gC;X.iVDs.I...| // 00000020 d3 63 d3 5a 0e 97 78 e6 74 ce a0 24 34 c1 66 7d |.c.Z..x.t..$4.f}| // 00000030 af 32 9e 59 22 f2 9a 67 3c ea e5 4f 54 6d 3e 07 |.2.Y"..g<..OTm>.| // 00000040 dc db 8a df 92 93 55 e0 19 8d 7c f5 58 a1 5a aa |......U...|.X.Z.| // 00000050 80 97 d9 48 84 2b f0 0d ab 39 2e d4 40 67 08 f4 |...H.+...9..@g..| // 00000060 56 b2 b5 3a e1 c8 8c f7 29 8a 13 75 59 98 ea ce |V..:....)..uY...| // 00000070 f4 6d d5 d0 62 85 51 8e fe d9 4a 02 1f 35 03 33 |.m..b.Q...J..5.3| // 00000080 03 37 8f df 75 d4 0b 9d 6c ba f1 c9 07 77 37 59 |.7..u...l....w7Y| // 00000090 1e cd 2a 18 75 93 18 c0 6d ee d8 d0 fc ad d5 00 |..*.u...m.......| // 000000a0 ab |.| // Signature 1: // 00000000 c0 c4 72 60 8e 83 8c 15 bf 56 d2 6f 1e 1a 9b 63 |..r`.....V.o...c| // 00000010 07 5f f4 6d fb 5b d4 fc 35 e2 46 52 53 41 3a 67 |._.m.[..5.FRSA:g| // 00000020 27 56 c5 3f 08 bb 99 6d 7d 0a f8 ac c5 29 e8 94 |'V.?...m}....)..| // 00000030 54 3e 4d fb ca b5 1d 9a 29 56 a0 09 f9 ec 6d b5 |T>M.....)V....m.| // 00000040 ac c5 1e 6a 65 72 46 a7 9c 11 d0 8c d0 d8 89 ad |...jerF.........| // 00000050 61 0c 2a 89 1a 4d af 86 49 8f 14 87 dd 64 0e 2f |a.*..M..I....d./| // 00000060 78 fd f8 95 ec ee a5 50 a8 65 b0 63 35 f2 83 05 |x......P.e.c5...| // 00000070 21 9d cf f1 0d a1 85 6a 3f ca 8d 68 31 1f e0 e2 |!......j?..h1...| // 00000080 03 37 8f df 75 d4 0b 9d 6c ba f1 c9 07 77 37 59 |.7..u...l....w7Y| // 00000090 1e cd 2a 18 75 93 18 c0 6d ee d8 d0 fc ad d5 00 |..*.u...m.......| // 000000a0 ab |.| // Signature 2: // 00000000 a4 8e 61 72 a4 72 18 81 55 df 8c e0 3a 01 92 05 |..ar.r..U...:...| // 00000010 f2 73 29 5a 6f 27 fd 55 d9 b4 a3 62 f2 e0 7f d3 |.s)Zo'.U...b....| // 00000020 1b 1e 8f 0b b0 e6 16 78 31 46 7f b6 32 90 f7 5e |.......x1F..2..^| // 00000030 ad fb ea 42 2b a6 46 ba fd c0 26 f3 21 af 31 9c |...B+.F...&.!.1.| // 00000040 a4 8b 48 7e 5a 4f eb 1d 1f c8 6c 96 e6 38 86 a9 |..H~ZO....l..8..| // 00000050 50 dc 69 e8 2d c9 ed 41 51 38 9d 5c 5f 9b e6 93 |P.i.-..AQ8.\_...| // 00000060 ef 3e 03 10 5e b1 0b 03 19 2c bb db 46 ef ad 1b |.>..^....,..F...| // 00000070 d6 25 92 98 92 aa 96 b5 d8 38 f8 5c b9 68 7a c2 |.%.......8.\.hz.| // 00000080 02 55 a2 af 44 5e 5b fb 65 b1 d5 6f ea 18 21 4a |.U..D^[.e..o..!J| // 00000090 4b 0a 75 3b 6e 50 b7 ed 9f e7 49 aa 03 83 d1 76 |K.u;nP....I....v| // 000000a0 7f |.| // Signature 3: // 00000000 43 cb 80 12 94 b9 f7 da e1 93 84 66 75 22 8b 8e |C..........fu"..| // 00000010 61 ff ed 65 f1 4e e4 3e ed 4d 98 3e 5c 6c 7a 2c |a..e.N.>.M.>\lz,| // 00000020 69 56 c6 9e 1b eb dd cd 02 42 d4 50 cf 66 7f 4f |iV.......B.P.f.O| // 00000030 c4 33 92 36 a0 b7 94 a5 3e fb 9b 19 bd 7c ea ce |.3.6....>....|..| // 00000040 69 84 bd 96 a9 6b 6e c2 47 03 9f 18 33 73 a5 2b |i....kn.G...3s.+| // 00000050 ee 11 e1 99 36 bf 44 42 26 5e f8 cc 25 1e 8a 97 |....6.DB&^..%...| // 00000060 30 06 bf af 76 ed 06 2d f6 ed 72 33 53 e4 8a e0 |0...v..-..r3S...| // 00000070 a8 88 84 48 69 dd 4b d9 ff e3 d7 4a cf 04 88 c9 |...Hi.K....J....| // 00000080 02 55 a2 af 44 5e 5b fb 65 b1 d5 6f ea 18 21 4a |.U..D^[.e..o..!J| // 00000090 4b 0a 75 3b 6e 50 b7 ed 9f e7 49 aa 03 83 d1 76 |K.u;nP....I....v| // 000000a0 7f |.| // Sig0 tag: 03378fdf75d40b9d6cbaf1c9077737591ecd2a18759318c06deed8d0fcadd500ab // Sig1 tag: 03378fdf75d40b9d6cbaf1c9077737591ecd2a18759318c06deed8d0fcadd500ab // Sig2 tag: 0255a2af445e5bfb65b1d56fea18214a4b0a753b6e50b7ed9fe749aa0383d1767f // Sig3 tag: 0255a2af445e5bfb65b1d56fea18214a4b0a753b6e50b7ed9fe749aa0383d1767f }
// This example implements Linkable Ring Signatures (LRS) generically // using the Camenisch/Stadler proof framework and HashProver. // // A ring signature proves that the signer owns one of a list of public keys, // without revealing anything about which public key the signer actually owns. // A linkable ring signature (LRS) is the same but includes a linkage tag, // which the signer proves to correspond 1-to-1 with the signer's key, // but whose relationship to the private key remains secret // from anyone who does not hold the private key. // A key-holder who signs multiple messages in the same public "linkage scope" // will be forced to use the same linkage tag in each such signature, // enabling others to tell whether two signatures in a given scope // were produced by the same or different signers. // // This scheme is conceptually similar to that of Liu/Wei/Wong in // "Linkable and Anonymous Signature for Ad Hoc Groups". // This example implementation is less space-efficient, however, // because it uses the generic HashProver for Fiat-Shamir noninteractivity // instead of Liu/Wei/Wong's customized hash-ring structure. // func ExampleHashProve_2() { // Crypto setup suite := openssl.NewAES128SHA256P256() rand := suite.Cipher([]byte("example")) B := suite.Point().Base() // standard base point // Create an anonymity ring of random "public keys" X := make([]abstract.Point, 3) for i := range X { // pick random points X[i], _ = suite.Point().Pick(nil, rand) } // Make just one of them an actual public/private keypair (X[mine],x) mine := 2 // only the signer knows this x := suite.Secret().Pick(rand) // create a private key x X[mine] = suite.Point().Mul(nil, x) // corresponding public key X // Produce the correct linkage tag for the signature, // as a pseudorandom base point multiplied by our private key. linkScope := []byte("The Linkage Scope") linkHash := suite.Cipher(linkScope) linkBase, _ := suite.Point().Pick(nil, linkHash) linkTag := suite.Point().Mul(linkBase, x) // Generate the proof predicate: an OR branch for each public key. sec := map[string]abstract.Secret{"x": x} pub := map[string]abstract.Point{"B": B, "BT": linkBase, "T": linkTag} preds := make([]Predicate, len(X)) for i := range X { name := fmt.Sprintf("X[%d]", i) // "X[0]","X[1]",... pub[name] = X[i] // public point value // Predicate indicates knowledge of the private key for X[i] // and correspondence of the key with the linkage tag preds[i] = And(Rep(name, "x", "B"), Rep("T", "x", "BT")) } pred := Or(preds...) // make a big Or predicate fmt.Printf("Linkable Ring Signature Predicate:\n\t%s\n", pred.String()) // The prover needs to know which Or branch (mine) is actually true. choice := make(map[Predicate]int) choice[pred] = mine // Generate the signature M := "Hello World!" // message we want to sign prover := pred.Prover(suite, sec, pub, choice) proof, _ := HashProve(suite, M, rand, prover) fmt.Print("Linkable Ring Signature:\n" + hex.Dump(proof)) // Verify the signature verifier := pred.Verifier(suite, pub) err := HashVerify(suite, M, verifier, proof) if err != nil { panic("signature failed to verify!") } fmt.Println("Linkable Ring Signature verified.") // Output: // Linkable Ring Signature Predicate: // (X[0]=x*B && T=x*BT) || (X[1]=x*B && T=x*BT) || (X[2]=x*B && T=x*BT) // Linkable Ring Signature: // 00000000 02 22 17 82 90 fd 63 78 91 37 12 26 0b 85 a4 5f |."....cx.7.&..._| // 00000010 c4 50 5d 4f 7c da 22 75 81 bd 85 a6 25 b3 ca d8 |.P]O|."u....%...| // 00000020 1b 02 d8 91 b8 82 2e 88 69 ba 47 5d 68 f7 8e 56 |........i.G]h..V| // 00000030 b5 f0 b9 93 c2 94 10 65 6f 1d 98 5f 17 a8 ef ec |.......eo.._....| // 00000040 45 04 03 f5 a9 11 32 0b f0 e6 87 a9 0f cd d7 c3 |E.....2.........| // 00000050 e8 9e 1f 47 0c 1b 10 52 de e0 4e fe 25 d4 4e 89 |...G...R..N.%.N.| // 00000060 97 35 6a 03 ef 39 35 1f fb 84 5c 1c 55 4d a4 d0 |.5j..95...\.UM..| // 00000070 36 9d 5b 2b 34 be 10 bf 6a bd 7f d9 a8 11 51 7c |6.[+4...j.....Q|| // 00000080 6c e7 6f b8 02 2f fc 10 c8 d6 40 23 e4 37 05 c5 |l.o../....@#.7..| // 00000090 b4 39 de a6 d1 85 f5 c0 be 57 76 83 c0 d4 8e ff |.9.......Wv.....| // 000000a0 2f 82 1e db 29 02 33 5b 1f 1b c5 b8 b5 fd 7b 77 |/...).3[......{w| // 000000b0 1c 32 06 3d b6 c0 6b 9b a6 d6 47 0c 51 69 2f 4f |.2.=..k...G.Qi/O| // 000000c0 2d 38 f5 46 82 a4 c6 f6 34 12 83 a0 32 2e 82 2c |-8.F....4...2..,| // 000000d0 4b fb b3 0c a1 4b a5 e3 27 43 b6 2f ed fa ca 4f |K....K..'C./...O| // 000000e0 93 83 fd 56 cc 43 71 eb 40 46 de 61 2f 08 8d 9a |[email protected]/...| // 000000f0 04 09 d7 a1 62 83 48 e3 cc 09 af 64 26 df df da |....b.H....d&...| // 00000100 d6 51 62 5d e6 2b 9f 75 01 e9 5a b8 dc ec 95 df |.Qb].+.u..Z.....| // 00000110 9d c9 4c f8 45 5e 3e fa 93 d6 5b 02 af 7b 66 26 |..L.E^>...[..{f&| // 00000120 b3 b4 5a a2 c0 1c 56 b2 b5 3a e1 c8 8c f7 29 8a |..Z...V..:....).| // 00000130 13 75 59 98 ea ce f4 6d d5 d0 62 85 51 8e fe d9 |.uY....m..b.Q...| // 00000140 4a 02 1f 35 03 33 d3 63 d3 5a 0e 97 78 e6 74 ce |J..5.3.c.Z..x.t.| // 00000150 a0 24 34 c1 66 7d af 32 9e 59 22 f2 9a 67 3c ea |.$4.f}.2.Y"..g<.| // 00000160 e5 4f 54 6d 3e 07 56 29 e3 95 12 f5 35 39 58 8a |.OTm>.V)....59X.| // 00000170 e3 a2 6e c0 4e b1 74 51 d8 2b 1e f7 7c 1d fe fc |..n.N.tQ.+..|...| // 00000180 75 29 8d f7 3e 18 |u)..>.| // Linkable Ring Signature verified. }
func Benchmark10PairShuffleOSSLP256(b *testing.B) { TestShuffle(openssl.NewAES128SHA256P256(), 10, b.N) }