github.com/cloudflare/circl@v1.5.0/group/ristretto255_test.go (about)

     1  package group
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/rand"
     6  	"encoding/hex"
     7  	"testing"
     8  )
     9  
    10  // https://tools.ietf.org/html/draft-irtf-cfrg-ristretto255-decaf448-00#appendix-A.1
    11  func TestGeneratorMultiples(t *testing.T) {
    12  	encVec := []string{
    13  		"0000000000000000000000000000000000000000000000000000000000000000",
    14  		"e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76",
    15  		"6a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919",
    16  		"94741f5d5d52755ece4f23f044ee27d5d1ea1e2bd196b462166b16152a9d0259",
    17  		"da80862773358b466ffadfe0b3293ab3d9fd53c5ea6c955358f568322daf6a57",
    18  		"e882b131016b52c1d3337080187cf768423efccbb517bb495ab812c4160ff44e",
    19  		"f64746d3c92b13050ed8d80236a7f0007c3b3f962f5ba793d19a601ebb1df403",
    20  		"44f53520926ec81fbd5a387845beb7df85a96a24ece18738bdcfa6a7822a176d",
    21  		"903293d8f2287ebe10e2374dc1a53e0bc887e592699f02d077d5263cdd55601c",
    22  		"02622ace8f7303a31cafc63f8fc48fdc16e1c8c8d234b2f0d6685282a9076031",
    23  		"20706fd788b2720a1ed2a5dad4952b01f413bcf0e7564de8cdc816689e2db95f",
    24  		"bce83f8ba5dd2fa572864c24ba1810f9522bc6004afe95877ac73241cafdab42",
    25  		"e4549ee16b9aa03099ca208c67adafcafa4c3f3e4e5303de6026e3ca8ff84460",
    26  		"aa52e000df2e16f55fb1032fc33bc42742dad6bd5a8fc0be0167436c5948501f",
    27  		"46376b80f409b29dc2b5f6f0c52591990896e5716f41477cd30085ab7f10301e",
    28  		"e0c418f7c8d9c4cdd7395b93ea124f3ad99021bb681dfc3302a9d99a2e53e64e",
    29  	}
    30  
    31  	g := Ristretto255
    32  	base := g.NewElement()
    33  	encBase, err := hex.DecodeString(encVec[0])
    34  	if err != nil {
    35  		t.Fatal("DecodeString")
    36  	}
    37  	err = base.UnmarshalBinary(encBase)
    38  	if err != nil {
    39  		t.Fatal("UnmarshalBinary")
    40  	}
    41  	if !base.IsIdentity() {
    42  		t.Fatal("Base element is not identity")
    43  	}
    44  
    45  	for i := 1; i < len(encVec); i++ {
    46  		base.Add(base, g.Generator())
    47  		baseEnc, err := base.MarshalBinary()
    48  		if err != nil {
    49  			t.Fatalf("MarshalBinary %d", i)
    50  		}
    51  		if hex.EncodeToString(baseEnc) != encVec[i] {
    52  			t.Fatalf("Multiple %d mismatch", i)
    53  		}
    54  	}
    55  }
    56  
    57  // https://tools.ietf.org/html/draft-irtf-cfrg-ristretto255-decaf448-00#appendix-A.2
    58  func TestInvalidEncodings(t *testing.T) {
    59  	encVec := []string{
    60  		// Non-canonical field encodings.
    61  		"00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
    62  		"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
    63  		// The internal ristretto255 implementation ignores the MSB, so the following two encodings fail.
    64  		// "f3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
    65  		// "edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
    66  		// Negative field elements.
    67  		"0100000000000000000000000000000000000000000000000000000000000000",
    68  		"01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
    69  		"ed57ffd8c914fb201471d1c3d245ce3c746fcbe63a3679d51b6a516ebebe0e20",
    70  		"c34c4e1826e5d403b78e246e88aa051c36ccf0aafebffe137d148a2bf9104562",
    71  		"c940e5a4404157cfb1628b108db051a8d439e1a421394ec4ebccb9ec92a8ac78",
    72  		"47cfc5497c53dc8e61c91d17fd626ffb1c49e2bca94eed052281b510b1117a24",
    73  		"f1c6165d33367351b0da8f6e4511010c68174a03b6581212c71c0e1d026c3c72",
    74  		"87260f7a2f12495118360f02c26a470f450dadf34a413d21042b43b9d93e1309",
    75  		// Non-square x^2.
    76  		"26948d35ca62e643e26a83177332e6b6afeb9d08e4268b650f1f5bbd8d81d371",
    77  		"4eac077a713c57b4f4397629a4145982c661f48044dd3f96427d40b147d9742f",
    78  		"de6a7b00deadc788eb6b6c8d20c0ae96c2f2019078fa604fee5b87d6e989ad7b",
    79  		"bcab477be20861e01e4a0e295284146a510150d9817763caf1a6f4b422d67042",
    80  		"2a292df7e32cababbd9de088d1d1abec9fc0440f637ed2fba145094dc14bea08",
    81  		"f4a9e534fc0d216c44b218fa0c42d99635a0127ee2e53c712f70609649fdff22",
    82  		"8268436f8c4126196cf64b3c7ddbda90746a378625f9813dd9b8457077256731",
    83  		"2810e5cbc2cc4d4eece54f61c6f69758e289aa7ab440b3cbeaa21995c2f4232b",
    84  		// Negative xy value.
    85  		"3eb858e78f5a7254d8c9731174a94f76755fd3941c0ac93735c07ba14579630e",
    86  		"a45fdc55c76448c049a1ab33f17023edfb2be3581e9c7aade8a6125215e04220",
    87  		"d483fe813c6ba647ebbfd3ec41adca1c6130c2beeee9d9bf065c8d151c5f396e",
    88  		"8a2e1d30050198c65a54483123960ccc38aef6848e1ec8f5f780e8523769ba32",
    89  		"32888462f8b486c68ad7dd9610be5192bbeaf3b443951ac1a8118419d9fa097b",
    90  		"227142501b9d4355ccba290404bde41575b037693cef1f438c47f8fbf35d1165",
    91  		"5c37cc491da847cfeb9281d407efc41e15144c876e0170b499a96a22ed31e01e",
    92  		"445425117cb8c90edcbc7c1cc0e74f747f2c1efa5630a967c64f287792a48a4b",
    93  		// s = -1, which causes y = 0.
    94  		"ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
    95  	}
    96  
    97  	for i, enc := range encVec {
    98  		raw, err := hex.DecodeString(enc)
    99  		if err != nil {
   100  			t.Fatal("DecodeString")
   101  		}
   102  		err = Ristretto255.NewElement().UnmarshalBinary(raw)
   103  		if err == nil {
   104  			t.Fatalf("Decode succeeded for vector %d: %v", i, enc)
   105  		}
   106  	}
   107  }
   108  
   109  func TestRistrettoElGamal(t *testing.T) {
   110  	g := Ristretto255
   111  	pk := g.NewElement()
   112  	sk := g.RandomScalar(rand.Reader)
   113  	pk.MulGen(sk)
   114  
   115  	// El'Gamal encrypt a random element p into a ciphertext-pair (c1,c2)
   116  	p := g.RandomElement(rand.Reader)
   117  	r := g.RandomScalar(rand.Reader)
   118  	c2 := g.NewElement()
   119  	c1 := g.NewElement()
   120  	c2.MulGen(r)
   121  	c1.Mul(pk, r)
   122  	c1.Add(c1, p)
   123  
   124  	// Decrypt (c1,c2) back to p
   125  	b := g.NewElement()
   126  	p2 := g.NewElement()
   127  	b.Mul(c2, sk)
   128  	p2.Add(c1, b.Neg(b))
   129  
   130  	if !p.IsEqual(p2) {
   131  		t.Fatal("Encryption/decryption failed")
   132  	}
   133  
   134  	pEnc, err := p.MarshalBinary()
   135  	if err != nil {
   136  		t.Fatal("MarshalBinary")
   137  	}
   138  	p2Enc, err := p2.MarshalBinary()
   139  	if err != nil {
   140  		t.Fatal("MarshalBinary")
   141  	}
   142  	if !bytes.Equal(pEnc, p2Enc) {
   143  		t.Fatal("Unequal encodings")
   144  	}
   145  }