LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // Package elgamal implements ElGamal encryption, suitable for OpenPGP, | 5 // Package elgamal implements ElGamal encryption, suitable for OpenPGP, |
6 // as specified in "A Public-Key Cryptosystem and a Signature Scheme Based on | 6 // as specified in "A Public-Key Cryptosystem and a Signature Scheme Based on |
7 // Discrete Logarithms," IEEE Transactions on Information Theory, v. IT-31, | 7 // Discrete Logarithms," IEEE Transactions on Information Theory, v. IT-31, |
8 // n. 4, 1985, pp. 469-472. | 8 // n. 4, 1985, pp. 469-472. |
9 // | 9 // |
10 // This form of ElGamal embeds PKCS#1 v1.5 padding, which may make it | 10 // This form of ElGamal embeds PKCS#1 v1.5 padding, which may make it |
(...skipping 19 matching lines...) Expand all Loading... |
30 PublicKey | 30 PublicKey |
31 X *big.Int | 31 X *big.Int |
32 } | 32 } |
33 | 33 |
34 // Encrypt encrypts the given message to the given public key. The result is a | 34 // Encrypt encrypts the given message to the given public key. The result is a |
35 // pair of integers. Errors can result from reading random, or because msg is | 35 // pair of integers. Errors can result from reading random, or because msg is |
36 // too large to be encrypted to the public key. | 36 // too large to be encrypted to the public key. |
37 func Encrypt(random io.Reader, pub *PublicKey, msg []byte) (c1, c2 *big.Int, err
os.Error) { | 37 func Encrypt(random io.Reader, pub *PublicKey, msg []byte) (c1, c2 *big.Int, err
os.Error) { |
38 pLen := (pub.P.BitLen() + 7) / 8 | 38 pLen := (pub.P.BitLen() + 7) / 8 |
39 if len(msg) > pLen-11 { | 39 if len(msg) > pLen-11 { |
40 » » err = os.ErrorString("elgamal: message too long") | 40 » » err = os.NewError("elgamal: message too long") |
41 return | 41 return |
42 } | 42 } |
43 | 43 |
44 // EM = 0x02 || PS || 0x00 || M | 44 // EM = 0x02 || PS || 0x00 || M |
45 em := make([]byte, pLen-1) | 45 em := make([]byte, pLen-1) |
46 em[0] = 2 | 46 em[0] = 2 |
47 ps, mm := em[1:len(em)-len(msg)-1], em[len(em)-len(msg):] | 47 ps, mm := em[1:len(em)-len(msg)-1], em[len(em)-len(msg):] |
48 err = nonZeroRandomBytes(ps, random) | 48 err = nonZeroRandomBytes(ps, random) |
49 if err != nil { | 49 if err != nil { |
50 return | 50 return |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 var lookingForIndex, index int | 90 var lookingForIndex, index int |
91 lookingForIndex = 1 | 91 lookingForIndex = 1 |
92 | 92 |
93 for i := 1; i < len(em); i++ { | 93 for i := 1; i < len(em); i++ { |
94 equals0 := subtle.ConstantTimeByteEq(em[i], 0) | 94 equals0 := subtle.ConstantTimeByteEq(em[i], 0) |
95 index = subtle.ConstantTimeSelect(lookingForIndex&equals0, i, in
dex) | 95 index = subtle.ConstantTimeSelect(lookingForIndex&equals0, i, in
dex) |
96 lookingForIndex = subtle.ConstantTimeSelect(equals0, 0, lookingF
orIndex) | 96 lookingForIndex = subtle.ConstantTimeSelect(equals0, 0, lookingF
orIndex) |
97 } | 97 } |
98 | 98 |
99 if firstByteIsTwo != 1 || lookingForIndex != 0 || index < 9 { | 99 if firstByteIsTwo != 1 || lookingForIndex != 0 || index < 9 { |
100 » » return nil, os.ErrorString("elgamal: decryption error") | 100 » » return nil, os.NewError("elgamal: decryption error") |
101 } | 101 } |
102 return em[index+1:], nil | 102 return em[index+1:], nil |
103 } | 103 } |
104 | 104 |
105 // nonZeroRandomBytes fills the given slice with non-zero random octets. | 105 // nonZeroRandomBytes fills the given slice with non-zero random octets. |
106 func nonZeroRandomBytes(s []byte, rand io.Reader) (err os.Error) { | 106 func nonZeroRandomBytes(s []byte, rand io.Reader) (err os.Error) { |
107 _, err = io.ReadFull(rand, s) | 107 _, err = io.ReadFull(rand, s) |
108 if err != nil { | 108 if err != nil { |
109 return | 109 return |
110 } | 110 } |
111 | 111 |
112 for i := 0; i < len(s); i++ { | 112 for i := 0; i < len(s); i++ { |
113 for s[i] == 0 { | 113 for s[i] == 0 { |
114 _, err = io.ReadFull(rand, s[i:i+1]) | 114 _, err = io.ReadFull(rand, s[i:i+1]) |
115 if err != nil { | 115 if err != nil { |
116 return | 116 return |
117 } | 117 } |
118 } | 118 } |
119 } | 119 } |
120 | 120 |
121 return | 121 return |
122 } | 122 } |
LEFT | RIGHT |