/* Returns the appropriate base-two padded bytes (assuming the underlying big representation remains b2c) */ func BigBytes(i *big.Int) (buff []byte) { ib := i.Bytes() shift := 0 shiftbyte := byte(0) switch i.Cmp(big.NewInt(0)) { case 1: // Positive must be padded if high-bit is 1 if ib[0]&0x80 == 0x80 { shift = 1 } case -1: // Negative numbers with a leading high-bit will also need // to be padded, but with a single bit tagging its 'negativity' if ib[0]&0x80 == 0x80 { shift = 1 shiftbyte = 0x80 } } buff = make([]byte, len(ib)+shift) if shift == 1 { buff[0] = shiftbyte } copy(buff[shift:], ib) return }
func (h *Hash) l3(m []byte, iter int) []byte { i := 0 k1 := new(big.Int) k2 := new(big.Int) for need := iter + 1; need > 0; i++ { t := h.kdf(224, 128*(i+1))[16*i : 16*(i+1)] k1.SetBytes(t[:8]) k2.SetBytes(t[8:]) if k1.Cmp(p64) == -1 && k2.Cmp(p64) == -1 { need-- } } mint := newInt(m) m1 := new(big.Int).Div(mint, p64p32) m2 := new(big.Int).Mod(mint, p64p32) y := new(big.Int).Add(m1, k1) y.Mul(y, new(big.Int).Add(m2, k2)) y.Mod(y, p64) Y := make([]byte, 8) copy(Y[8-len(y.Bytes()):], y.Bytes()) return Y }
// Sign signs an arbitrary length hash (which should be the result of hashing a // larger message) using the private key, priv. It returns the signature as a // pair of integers. The security of the private key depends on the entropy of // rand. func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err os.Error) { // See [NSA] 3.4.1 c := priv.PublicKey.Curve var k, kInv *big.Int for { for { k, err = randFieldElement(c, rand) if err != nil { r = nil return } kInv = new(big.Int).ModInverse(k, c.N) r, _ = priv.Curve.ScalarBaseMult(k.Bytes()) r.Mod(r, priv.Curve.N) if r.Sign() != 0 { break } } e := hashToInt(hash, c) s = new(big.Int).Mul(priv.D, r) s.Add(s, e) s.Mul(s, kInv) s.Mod(s, priv.PublicKey.Curve.N) if s.Sign() != 0 { break } } return }
// Decrypt takes two integers, resulting from an ElGamal encryption, and // returns the plaintext of the message. An error can result only if the // ciphertext is invalid. Users should keep in mind that this is a padding // oracle and thus, if exposed to an adaptive chosen ciphertext attack, can // be used to break the cryptosystem. See ``Chosen Ciphertext Attacks // Against Protocols Based on the RSA Encryption Standard PKCS #1'', Daniel // Bleichenbacher, Advances in Cryptology (Crypto '98), func Decrypt(priv *PrivateKey, c1, c2 *big.Int) (msg []byte, err error) { s := new(big.Int).Exp(c1, priv.X, priv.P) s.ModInverse(s, priv.P) s.Mul(s, c2) s.Mod(s, priv.P) em := s.Bytes() firstByteIsTwo := subtle.ConstantTimeByteEq(em[0], 2) // The remainder of the plaintext must be a string of non-zero random // octets, followed by a 0, followed by the message. // lookingForIndex: 1 iff we are still looking for the zero. // index: the offset of the first zero byte. var lookingForIndex, index int lookingForIndex = 1 for i := 1; i < len(em); i++ { equals0 := subtle.ConstantTimeByteEq(em[i], 0) index = subtle.ConstantTimeSelect(lookingForIndex&equals0, i, index) lookingForIndex = subtle.ConstantTimeSelect(equals0, 0, lookingForIndex) } if firstByteIsTwo != 1 || lookingForIndex != 0 || index < 9 { return nil, errors.New("elgamal: decryption error") } return em[index+1:], nil }
func (curve *Curve) Multiply(n *big.Int, p *Point) *Point { if p == nil { //fmt.Printf("p == nil!?wtfbbq\n") return p } bytes := n.Bytes() length := len(bytes) bitlength := length * 8 fmt.Printf("length = %d\n", bitlength) var rightmost uint = 0x01 //fmt.Printf("leftmost = %d\n", leftmost) p2 := p last_i := bitlength - 1 var ptotal *Point ptotal = nil for i := bitlength - 1; i >= 0; i-- { //fmt.Printf("\n(i mod 8) = %d \n", 7-(i%8)) if uint(rightmost<<uint(7-(i%8)))&uint(bytes[i/8]) != 0 { for j := last_i; j > i; j-- { //fmt.Printf("Doubling! i=%d\n",i) p2 = curve.double(p2) } last_i = i fmt.Printf("last_i = %d\n", last_i) ptotal = curve.Add(p2, ptotal) } } return ptotal }
// Vygeneruje "nahodne" nenulove cislo mensi nez n func RandNumSmaller(n *big.Int) (r *big.Int) { r = big.NewInt(0) for r.Cmp(big0) == 0 { bytes := randBytes(len(n.Bytes()) * 8) r.SetBytes(bytes) r.Mod(r, n) } return }
// Set the public key (the value E and N) func (k *RR_DNSKEY) setPublicKeyRSA(_E int, _N *big.Int) bool { if _E == 0 || _N == nil { return false } buf := exponentToBuf(_E) buf = append(buf, _N.Bytes()...) k.PublicKey = unpackBase64(buf) return true }
func BenchmarkBaseMult(b *testing.B) { b.ResetTimer() p224 := P224() e := p224BaseMultTests[25] k, _ := new(big.Int).SetString(e.k, 10) b.StartTimer() for i := 0; i < b.N; i++ { p224.ScalarBaseMult(k.Bytes()) } }
//TODO: test more curves? func BenchmarkBaseMult(b *testing.B) { b.ResetTimer() s256 := S224() e := s256BaseMultTests[0] //TODO: check, used to be 25 instead of 0, but it's probably ok k, _ := new(big.Int).SetString(e.k, 16) b.StartTimer() for i := 0; i < b.N; i++ { s256.ScalarBaseMult(k.Bytes()) } }
// rawValueForBig returns an asn1.RawValue which represents the given integer. func rawValueForBig(n *big.Int) asn1.RawValue { b := n.Bytes() if n.Sign() >= 0 && len(b) > 0 && b[0]&0x80 != 0 { // This positive number would be interpreted as a negative // number in ASN.1 because the MSB is set. padded := make([]byte, len(b)+1) copy(padded[1:], b) b = padded } return asn1.RawValue{Tag: 2, Bytes: b} }
// Marshal converts a point into the form specified in section 4.3.6 of ANSI // X9.62. func (curve *Curve) Marshal(x, y *big.Int) []byte { byteLen := (curve.BitSize + 7) >> 3 ret := make([]byte, 1+2*byteLen) ret[0] = 4 // uncompressed point xBytes := x.Bytes() copy(ret[1+byteLen-len(xBytes):], xBytes) yBytes := y.Bytes() copy(ret[1+2*byteLen-len(yBytes):], yBytes) return ret }
func (h *Hash) Sum() []byte { hashed := h.vhash() pad := h.pdf() sum := make([]byte, h.size) for i := 0; i < h.size/8; i++ { lo := 8 * i hi := 8 * (i + 1) t := new(big.Int).Add(newInt(pad[lo:hi]), newInt(hashed[lo:hi])) t.Mod(t, m64) copy(sum[hi-len(t.Bytes()):hi], t.Bytes()) } return sum }
//TODO: check func Big2Hex32(b *big.Int) [32]byte { var answer [32]byte tmp := b.Bytes() if len(tmp) <= 32 { for i := 0; i < len(tmp); i++ { answer[31-i] = tmp[i] } } return answer }
func TestBaseMult(t *testing.T) { p224 := P224() for i, e := range p224BaseMultTests { k, ok := new(big.Int).SetString(e.k, 10) if !ok { t.Errorf("%d: bad value for k: %s", i, e.k) } x, y := p224.ScalarBaseMult(k.Bytes()) if fmt.Sprintf("%x", x) != e.x || fmt.Sprintf("%x", y) != e.y { t.Errorf("%d: bad output for k=%s: got (%x, %s), want (%s, %s)", i, e.k, x, y, e.x, e.y) } } }
//TODO: test different curves as well? func TestBaseMult(t *testing.T) { s256 := S256() for i, e := range s256BaseMultTests { k, ok := new(big.Int).SetString(e.k, 16) if !ok { t.Errorf("%d: bad value for k: %s", i, e.k) } x, y := s256.ScalarBaseMult(k.Bytes()) if fmt.Sprintf("%X", x) != e.x || fmt.Sprintf("%X", y) != e.y { t.Errorf("%d: bad output for k=%s: got (%X, %X), want (%s, %s)", i, e.k, x, y, e.x, e.y) } if testing.Short() && i > 5 { break } } }
func marshalInt(to []byte, n *big.Int) []byte { lengthBytes := to to = to[4:] length := 0 if n.Sign() < 0 { // A negative number has to be converted to two's-complement // form. So we'll subtract 1 and invert. If the // most-significant-bit isn't set then we'll need to pad the // beginning with 0xff in order to keep the number negative. nMinus1 := new(big.Int).Neg(n) nMinus1.Sub(nMinus1, bigOne) bytes := nMinus1.Bytes() for i := range bytes { bytes[i] ^= 0xff } if len(bytes) == 0 || bytes[0]&0x80 == 0 { to[0] = 0xff to = to[1:] length++ } nBytes := copy(to, bytes) to = to[nBytes:] length += nBytes } else if n.Sign() == 0 { // A zero is the zero length string } else { bytes := n.Bytes() if len(bytes) > 0 && bytes[0]&0x80 != 0 { // We'll have to pad this with a 0x00 in order to // stop it looking like a negative number. to[0] = 0 to = to[1:] length++ } nBytes := copy(to, bytes) to = to[nBytes:] length += nBytes } lengthBytes[0] = byte(length >> 24) lengthBytes[1] = byte(length >> 16) lengthBytes[2] = byte(length >> 8) lengthBytes[3] = byte(length) return to }
func marshalBigInt(out *forkableWriter, n *big.Int) (err os.Error) { if n.Sign() < 0 { // A negative number has to be converted to two's-complement // form. So we'll subtract 1 and invert. If the // most-significant-bit isn't set then we'll need to pad the // beginning with 0xff in order to keep the number negative. nMinus1 := new(big.Int).Neg(n) nMinus1.Sub(nMinus1, bigOne) bytes := nMinus1.Bytes() for i := range bytes { bytes[i] ^= 0xff } if len(bytes) == 0 || bytes[0]&0x80 == 0 { err = out.WriteByte(0xff) if err != nil { return } } _, err = out.Write(bytes) } else if n.Sign() == 0 { // Zero is written as a single 0 zero rather than no bytes. err = out.WriteByte(0x00) } else { bytes := n.Bytes() if len(bytes) > 0 && bytes[0]&0x80 != 0 { // We'll have to pad this with 0x00 in order to stop it // looking like a negative number. err = out.WriteByte(0) if err != nil { return } } _, err = out.Write(bytes) } return }
// Set the public key for X and Y for Curve // Experimental func curveToBuf(_X, _Y *big.Int) []byte { buf := _X.Bytes() buf = append(buf, _Y.Bytes()...) return buf }
// Spocita msg^key % mod func crypt(key, mod *big.Int, msg []byte) []byte { a := new(big.Int).SetBytes(msg) a.Exp(a, key, mod) return a.Bytes() }
func main() { flag.Parse() // parsovani parametru prikazove radky rand.Seed(time.Nanoseconds()) // inicializace generatoru nahodnych cisel if *generateKeys { SaveKeys(GenerateKeys(*keyLength)) } // rozdeleni souboru na vice mensich podle delky klice if *splitFile != "" { rights := 0600 n, _ := ReadPublicKey() bytes := readFile(*splitFile) nl := len(n.Bytes()) - 1 i := 0 for ; i < len(bytes)/nl; i++ { writeToFile(partfile(i), bytes[i*nl:(i+1)*nl], rights) } if len(bytes[i*nl:]) > 0 { // pokud deleni nevychazi presne writeToFile(partfile(i), bytes[i*nl:], rights) i++ } // informacni soubor writeToFile(*prefix+".info", strings.Bytes(fmt.Sprintf("%d", i)), rights) } // zasifruje/rozsifruje vsechny soubory verejnym klicem if *encrypFiles { n, e := ReadPublicKey() max := msgscount() for i := 0; i < max; i++ { file := readFile(partfile(i)) bs := crypt(e, n, file) writeToFile(partfile(i), bs, 0600) } } // rozsifruje/zasifruje vsechny soubory soukromym klicem if *decrypFiles { p, q, d := ReadPrivateKey() pinv := new(big.Int).Mul(p, invMod(p, q)) // = p*(p^-1 mod q) qinv := new(big.Int).Mul(q, invMod(q, p)) // = q*(q^-1 mod p) n := new(big.Int).Mul(p, q) max := msgscount() for i := 0; i < max; i++ { file := readFile(partfile(i)) // CINSKA VETA O ZBYTCICH bp := new(big.Int).SetBytes(crypt(d, p, file)) // decrypt mod p bq := new(big.Int).SetBytes(crypt(d, q, file)) // decrypt mod q // bs = bp * qinv + bq * binv (mod n) bs := new(big.Int).Mul(bp, qinv) bs.Add(bs, new(big.Int).Mul(bq, pinv)) bs.Mod(bs, n) writeToFile(partfile(i), bs.Bytes(), 0600) } } // spojeni souboru do jednoho if *joinFile != "" { max := msgscount() var bs []byte for i := 0; i < max; i++ { file := readFile(partfile(i)) bs = bytes.Add(bs, file) } writeToFile(*joinFile, bs, 0600) } }
// writeBig serializes a *big.Int to w. func writeBig(w io.Writer, i *big.Int) os.Error { return writeMPI(w, uint16(i.BitLen()), i.Bytes()) }
func fromBig(n *big.Int) parsedMPI { return parsedMPI{ bytes: n.Bytes(), bitLength: uint16(n.BitLen()), } }