anon

package
v0.0.0-...-0b3308b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 19, 2017 License: MPL-2.0 Imports: 8 Imported by: 1

Documentation

Overview

Package anon implements cryptographic primitives for anonymous communication.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Decrypt

func Decrypt(suite abstract.Suite, ciphertext []byte, anonymitySet Set,
	mine int, privateKey abstract.Scalar, hide bool) ([]byte, error)

Decrypt a message encrypted for a particular anonymity set. Returns the cleartext message on success, or an error on failure.

The caller provides the anonymity set for which the message is intended, and the private key corresponding to one of the public keys in the set. Decrypt verifies that the message is encrypted correctly for this set - in particular, that it could be decrypted by ALL of the listed members - before returning successfully with the decrypted message. This verification ensures that a malicious sender cannot de-anonymize a receiver by constructing a ciphertext incorrectly so as to be decryptable by only some members of the set. As a side-effect, this verification also ensures plaintext-awareness: that is, it is infeasible for a sender to construct any ciphertext that will be accepted by the receiver without knowing the plaintext.

func Encrypt

func Encrypt(suite abstract.Suite, rand cipher.Stream, message []byte,
	anonymitySet Set, hide bool) []byte

Encrypt a message for reading by any member of an explit anonymity set. The caller supplies one or more keys representing the anonymity set. If the provided set contains only one public key, this reduces to conventional single-receiver public-key encryption.

If hide is true, Encrypt will produce a uniformly random-looking byte-stream, which reveals no metadata other than message length to anyone unable to decrypt the message. The provided abstract.Suite must support uniform-representation encoding of public keys for this to work.

Example (AnonSet)
// Crypto setup
suite := nist.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.Scalar().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  04 a4 2a cf e6 41 38 3f  d4 df 6e f4 70 05 a8 ec  |..*..A8?..n.p...|
00000010  55 8a a5 a4 73 7f 34 ae  1c 50 69 fe af e4 71 01  |U...s.4..Pi...q.|
00000020  51 33 a7 89 e2 f0 85 81  ce e9 bc d2 49 cb aa 9a  |Q3..........I...|
00000030  55 c5 99 ad 5c a5 e4 36  e4 71 c8 c1 58 4c f7 aa  |U...\..6.q..XL..|
00000040  2f 3f d2 9a ec 4b fd 85  5e 1b 7f 08 3b 82 12 75  |/?...K..^...;..u|
00000050  76 e5 b2 0a 48 d1 d1 9a  5f 45 eb 57 e6 5b 4c 81  |v...H..._E.W.[L.|
00000060  10 d7 98 e0 f4 ce 98 9f  94 66 28 8d c4 ff 61 3f  |.........f(...a?|
00000070  2a 61 c1 31 f8 b5 60 b7  82 05 64 e4 cd 86 66 43  |*a.1..`...d...fC|
00000080  f1 c1 de 23 d5 ea 19 ba  dd 27 fa 4c 66 d8 a0 19  |...#.....'.Lf...|
00000090  1e 6c ea 70 b7 71 8f b5  cd 3a 49 6d c3 03 08 e0  |.l.p.q...:Im....|
000000a0  4d d6 67 9c 02 67 38 c2  d8 78 0d fd 97 f2 2b 8b  |M.g..g8..x....+.|
000000b0  b3 b2 ae 0d f1 2b 1c 1b  13 9d 71 75 b8           |.....+....qu.|
Decrypted: 'Hello World!'

func Sign

func Sign(suite abstract.Suite, random cipher.Stream, message []byte,
	anonymitySet Set, linkScope []byte, mine int, privateKey abstract.Scalar) []byte

Sign creates an optionally anonymous, optionally linkable signature on a given message.

The caller supplies one or more public keys representing an anonymity set, and the private key corresponding to one of those public keys. The resulting signature proves to a verifier that the owner of one of these public keys signed the message, without revealing which key-holder signed the message, offering anonymity among the members of this explicit anonymity set. The other users whose keys are listed in the anonymity set need not consent or even be aware that they have been included in an anonymity set: anyone having a suitable public key may be "conscripted" into a set.

If the provided anonymity set contains only one public key (the signer's), then this function produces a traditional non-anonymous signature, equivalent in both size and performance to a standard ElGamal signature.

The caller may request either unlinkable or linkable anonymous signatures. If linkScope is nil, this function generates an unlinkable signature, which contains no information about which member signed the message. The anonymity provided by unlinkable signatures is forward-secure, in that a signature reveals nothing about which member generated it, even if all members' private keys are later released. For cryptographic background on unlinkable anonymity-set signatures - also known as ring signatures or ad-hoc group signatures - see Rivest, "How to Leak a Scalar" at http://people.csail.mit.edu/rivest/RivestShamirTauman-HowToLeakAScalar.pdf.

If the caller passes a non-nil linkScope, the resulting anonymous signature will be linkable. This means that given two signatures produced using the same linkScope, a verifier will be able to tell whether the same or different anonymity set members produced those signatures. In particular, verifying a linkable signature yields a linkage tag. This linkage tag has a 1-to-1 correspondence with the signer's public key within a given linkScope, but is cryptographically unlinkable to either the signer's public key or to linkage tags in other scopes. The provided linkScope may be an arbitrary byte-string; the only significance these scopes have is whether they are equal or unequal. For details on the linkable signature algorithm this function implements, see Liu/Wei/Wong, "Linkable Spontaneous Anonymous Group Signature for Ad Hoc Groups" at http://www.cs.cityu.edu.hk/~duncan/papers/04liuetal_lsag.pdf.

Linkage tags may be used to protect against sock-puppetry or Sybil attacks in situations where a verifier needs to know how many distinct members of an anonymity set are present or signed messages in a given context. It is cryptographically hard for one anonymity set member to produce signatures with different linkage tags in the same scope. An important and fundamental downside, however, is that linkable signatures do NOT offer forward-secure anonymity. If an anonymity set member's private key is later released, it is trivial to check whether or not that member produced a given signature. Also, anonymity set members who did NOT sign a message could (voluntarily or under coercion) prove that they did not sign it, e.g., simply by signing some other message in that linkage context and noting that the resulting linkage tag comes out different. Thus, linkable anonymous signatures are not appropriate to use in situations where there may be significant risk that members' private keys may later be compromised, or that members may be persuaded or coerced into revealing whether or not they produced a signature of interest.

Example (AnonSet)

This example demonstrates how to create unlinkable anonymity-set signatures, and to verify them, using a small anonymity set containing three public keys.

// Crypto setup
suite := nist.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.Scalar().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  eb 16 0d c9 1e 19 f5 da  f7 9b 77 7d 52 0b f1 82  |..........w}R...|
00000010  4b e3 dd 6c 44 f3 6f fe  c3 c1 1a 6e 1f a8 43 26  |K..lD.o....n..C&|
00000020  63 d3 5a 0e 97 78 e6 74  ce a0 24 34 c1 66 7d af  |c.Z..x.t..$4.f}.|
00000030  32 9e 59 22 f2 9a 67 3c  ea e5 4f 54 6d 3e 07 f1  |2.Y"..g<..OTm>..|
00000040  63 10 77 96 09 a3 c1 e4  85 f8 d9 97 0c 47 dc 73  |c.w..........G.s|
00000050  da 6c d8 11 8a 2e 00 a7  f2 01 45 e0 91 4e 28 d6  |.l........E..N(.|
00000060  b2 b5 3a e1 c8 8c f7 29  8a 13 75 59 98 ea ce f4  |..:....)..uY....|
00000070  6d d5 d0 62 85 51 8e fe  d9 4a 02 1f 35 03 33 d3  |m..b.Q...J..5.3.|
Signature verified against correct message.
Verifying against wrong message: invalid signature
Example (Linkable)

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.

// Crypto setup
suite := nist.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.Scalar().Pick(rand) // create a private key x
x2 := suite.Scalar().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  c6 e9 27 a5 00 5d 22 40  d2 a2 5d 08 44 2b ec 2e  |..'..]"@..].D+..|
00000010  e2 01 a6 85 70 70 b4 73  2c 18 24 f1 46 44 22 09  |....pp.s,.$.FD".|
00000020  1e 6d 18 7f 8b 95 e3 c4  b9 33 ad 94 69 b5 b4 13  |.m.......3..i...|
00000030  b8 51 2f 24 a7 98 e4 06  f4 b2 f3 ee e8 73 de 78  |.Q/$.........s.x|
00000040  a3 9d 4b 1c 74 6f 3a 50  89 c9 10 cc bb b0 5c a7  |..K.to:P......\.|
00000050  09 a9 23 47 0f 36 08 a4  f3 46 ad 14 2d f0 9d c1  |..#G.6...F..-...|
00000060  63 d3 5a 0e 97 78 e6 74  ce a0 24 34 c1 66 7d af  |c.Z..x.t..$4.f}.|
00000070  32 9e 59 22 f2 9a 67 3c  ea e5 4f 54 6d 3e 07 f1  |2.Y"..g<..OTm>..|
00000080  04 00 33 42 ee 88 9f 5d  fa 2e be 6a 72 fd 67 22  |..3B...]...jr.g"|
00000090  c1 e0 ed 35 69 d7 e4 67  df 92 e7 ca 75 2f e6 72  |...5i..g....u/.r|
000000a0  79 3a 32 e2 8b 45 61 e8  7d e5 95 5b 0a 30 35 e9  |y:2..Ea.}..[.05.|
000000b0  af 3c 41 48 59 d9 e2 73  68 77 31 f3 36 cc ee 78  |.<AHY..shw1.6..x|
000000c0  ab                                                |.|
Signature 1:
00000000  69 4c 29 32 cb 9c f6 ca  80 72 f6 25 e0 ef 44 0b  |iL)2.....r.%..D.|
00000010  f2 0b e3 ab 98 c4 62 a3  10 13 09 02 9a f1 f1 00  |......b.........|
00000020  7f 03 ca 4f 75 84 fe 06  2c 9c 64 0e 99 c6 f1 91  |...Ou...,.d.....|
00000030  62 43 48 b6 f8 20 41 2b  fa 59 e7 35 be f8 4c 1b  |bCH.. A+.Y.5..L.|
00000040  f0 d8 af 83 ad 9a 87 55  ca be 46 f9 42 a2 dd 18  |.......U..F.B...|
00000050  18 83 f1 f5 6d 82 e5 38  49 bf 24 9e 80 a4 12 eb  |....m..8I.$.....|
00000060  56 c5 3f 08 bb 99 6d 7d  0a f8 ac c5 29 e8 94 54  |V.?...m}....)..T|
00000070  3e 4d fb ca b5 1d 9a 29  56 a0 09 f9 ec 6d b5 28  |>M.....)V....m.(|
00000080  04 00 33 42 ee 88 9f 5d  fa 2e be 6a 72 fd 67 22  |..3B...]...jr.g"|
00000090  c1 e0 ed 35 69 d7 e4 67  df 92 e7 ca 75 2f e6 72  |...5i..g....u/.r|
000000a0  79 3a 32 e2 8b 45 61 e8  7d e5 95 5b 0a 30 35 e9  |y:2..Ea.}..[.05.|
000000b0  af 3c 41 48 59 d9 e2 73  68 77 31 f3 36 cc ee 78  |.<AHY..shw1.6..x|
000000c0  ab                                                |.|
Signature 2:
00000000  94 d0 51 98 05 a1 79 6c  16 4e 7f f2 58 c8 09 b8  |..Q...yl.N..X...|
00000010  32 12 a5 dc be f3 cf 08  a8 77 8f 7e a7 32 dd 2b  |2........w.~.2.+|
00000020  8b 48 7e 5a 4f eb 1d 1f  c8 6c 96 e6 38 86 a9 50  |.H~ZO....l..8..P|
00000030  dc 69 e8 2d c9 ed 41 51  38 9d 5c 5f 9b e6 93 aa  |.i.-..AQ8.\_....|
00000040  1c f7 7d 2f d1 ad 5c cd  4d ab 3a ed 2f 29 08 81  |..}/..\.M.:./)..|
00000050  55 61 40 8d 86 88 cd e6  62 be 28 b4 90 9c ae 69  |Ua@.....b.(....i|
00000060  54 1a 20 09 f3 84 ad 29  dc a8 64 cf c6 ec 92 f0  |T. ....)..d.....|
00000070  76 0f 36 28 66 88 81 2b  59 43 0c 69 6f f2 7a 8e  |v.6(f..+YC.io.z.|
00000080  04 80 18 09 20 80 e9 9b  39 bc 17 47 55 13 8f c9  |.... ...9..GU...|
00000090  b4 9d 11 78 7b 56 0f f6  db 38 5f b4 f1 4f 3f 93  |...x{V...8_..O?.|
000000a0  63 9c 33 ea 86 f6 e1 54  79 c9 14 9f 45 b6 88 59  |c.3....Ty...E..Y|
000000b0  49 b6 76 99 c7 0c 84 6d  1a 9e 05 b0 30 c1 48 f2  |I.v....m....0.H.|
000000c0  9a                                                |.|
Signature 3:
00000000  1a 64 49 4a ff 66 bc 88  93 54 30 e9 96 89 34 76  |.dIJ.f...T0...4v|
00000010  f6 95 e0 a9 84 8a a2 6e  f4 5e 7f db 58 d9 8a 48  |.......n.^..X..H|
00000020  84 bd 96 a9 6b 6e c2 47  03 9f 18 33 73 a5 2b ee  |....kn.G...3s.+.|
00000030  11 e1 99 36 bf 44 42 26  5e f8 cc 25 1e 8a 97 2b  |...6.DB&^..%...+|
00000040  7f 57 93 33 c5 fb 27 9f  24 e9 d4 3f 1c 16 67 4c  |.W.3..'.$..?..gL|
00000050  50 0b d1 0b 08 9b 0f 3f  cb ac 96 e8 92 3c a5 3d  |P......?.....<.=|
00000060  d4 83 2c dd c6 6d e4 68  67 b7 dc 39 68 77 de 3d  |..,..m.hg..9hw.=|
00000070  8c 83 0d b2 24 4b d6 17  e4 ce 78 7a 63 b7 f0 bb  |....$K....xzc...|
00000080  04 80 18 09 20 80 e9 9b  39 bc 17 47 55 13 8f c9  |.... ...9..GU...|
00000090  b4 9d 11 78 7b 56 0f f6  db 38 5f b4 f1 4f 3f 93  |...x{V...8_..O?.|
000000a0  63 9c 33 ea 86 f6 e1 54  79 c9 14 9f 45 b6 88 59  |c.3....Ty...E..Y|
000000b0  49 b6 76 99 c7 0c 84 6d  1a 9e 05 b0 30 c1 48 f2  |I.v....m....0.H.|
000000c0  9a                                                |.|
Sig0 tag: 04003342ee889f5dfa2ebe6a72fd6722c1e0ed3569d7e467df92e7ca752fe672793a32e28b4561e87de5955b0a3035e9af3c414859d9e273687731f336ccee78ab
Sig1 tag: 04003342ee889f5dfa2ebe6a72fd6722c1e0ed3569d7e467df92e7ca752fe672793a32e28b4561e87de5955b0a3035e9af3c414859d9e273687731f336ccee78ab
Sig2 tag: 048018092080e99b39bc174755138fc9b49d11787b560ff6db385fb4f14f3f93639c33ea86f6e15479c9149f45b6885949b67699c70c846d1a9e05b030c148f29a
Sig3 tag: 048018092080e99b39bc174755138fc9b49d11787b560ff6db385fb4f14f3f93639c33ea86f6e15479c9149f45b6885949b67699c70c846d1a9e05b030c148f29a

func Verify

func Verify(suite abstract.Suite, message []byte, anonymitySet Set,
	linkScope []byte, signatureBuffer []byte) ([]byte, error)

Verify checks a signature generated by Sign.

The caller provides the message, anonymity set, and linkage scope with which the signature was purportedly produced. If the signature is a valid linkable signature (linkScope != nil), this function returns a linkage tag that uniquely corresponds to the signer within the given linkScope. If the signature is a valid unlinkable signature (linkScope == nil), returns an empty but non-nil byte-slice instead of a linkage tag on success. Returns a nil linkage tag and an error if the signature is invalid.

Types

type PriKey

type PriKey struct {
	Set                  // Public key-set
	Mine int             // Index of the public key I own
	Pri  abstract.Scalar // Private key for that public key
}

A private key representing a member of an anonymity set

type SKEME

type SKEME struct {
	// contains filtered or unexported fields
}

Pairwise anonymous key agreement for point-to-point interactions. We use the encryption-based SKEME authenticated key exchange protocol, with the anonymity-set encryption, to authenticate a Diffie-Hellman secret. The result is a private two-party communication channel, where each party knows that the other is a member of a specific set, but does not know the other's price identity unless his set is of size one. Once we have performed this key agreement, we can use more efficient pairwise cryptographic primitives such as GCM authenticators, which are not directly usable in multiparty contexts.

func (*SKEME) Init

func (sk *SKEME) Init(suite abstract.Suite, rand cipher.Stream,
	lpri PriKey, rpub Set, hide bool)

Initialize...

func (*SKEME) Recv

func (sk *SKEME) Recv(rm []byte) (bool, error)

func (*SKEME) ToSend

func (sk *SKEME) ToSend() []byte

Return the current message that should be sent (retransmitting if needed)

type Set

type Set []abstract.Point

An anon.Set represents an explicit anonymity set as a list of public keys.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL