migrate to go modules from vndr
Signed-off-by: Tariq Ibrahim <tariq181290@gmail.com>
This commit is contained in:
parent
dcfe05ce6c
commit
5223c27422
503 changed files with 273730 additions and 9491 deletions
3
vendor/golang.org/x/crypto/AUTHORS
generated
vendored
Normal file
3
vendor/golang.org/x/crypto/AUTHORS
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
# This source code refers to The Go Authors for copyright purposes.
|
||||
# The master list of authors is in the main Go distribution,
|
||||
# visible at https://tip.golang.org/AUTHORS.
|
3
vendor/golang.org/x/crypto/CONTRIBUTORS
generated
vendored
Normal file
3
vendor/golang.org/x/crypto/CONTRIBUTORS
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
# This source code was written by the Go contributors.
|
||||
# The master list of contributors is in the main Go distribution,
|
||||
# visible at https://tip.golang.org/CONTRIBUTORS.
|
21
vendor/golang.org/x/crypto/README.md
generated
vendored
21
vendor/golang.org/x/crypto/README.md
generated
vendored
|
@ -1,21 +0,0 @@
|
|||
# Go Cryptography
|
||||
|
||||
This repository holds supplementary Go cryptography libraries.
|
||||
|
||||
## Download/Install
|
||||
|
||||
The easiest way to install is to run `go get -u golang.org/x/crypto/...`. You
|
||||
can also manually git clone the repository to `$GOPATH/src/golang.org/x/crypto`.
|
||||
|
||||
## Report Issues / Send Patches
|
||||
|
||||
This repository uses Gerrit for code changes. To learn how to submit changes to
|
||||
this repository, see https://golang.org/doc/contribute.html.
|
||||
|
||||
The main issue tracker for the crypto repository is located at
|
||||
https://github.com/golang/go/issues. Prefix your issue with "x/crypto:" in the
|
||||
subject line, so it is easy to find.
|
||||
|
||||
Note that contributions to the cryptography package receive additional scrutiny
|
||||
due to their sensitive nature. Patches may take longer than normal to receive
|
||||
feedback.
|
43
vendor/golang.org/x/crypto/acme/acme.go
generated
vendored
43
vendor/golang.org/x/crypto/acme/acme.go
generated
vendored
|
@ -77,6 +77,10 @@ const (
|
|||
type Client struct {
|
||||
// Key is the account key used to register with a CA and sign requests.
|
||||
// Key.Public() must return a *rsa.PublicKey or *ecdsa.PublicKey.
|
||||
//
|
||||
// The following algorithms are supported:
|
||||
// RS256, ES256, ES384 and ES512.
|
||||
// See RFC7518 for more details about the algorithms.
|
||||
Key crypto.Signer
|
||||
|
||||
// HTTPClient optionally specifies an HTTP client to use
|
||||
|
@ -124,11 +128,7 @@ func (c *Client) Discover(ctx context.Context) (Directory, error) {
|
|||
return *c.dir, nil
|
||||
}
|
||||
|
||||
dirURL := c.DirectoryURL
|
||||
if dirURL == "" {
|
||||
dirURL = LetsEncryptURL
|
||||
}
|
||||
res, err := c.get(ctx, dirURL, wantStatus(http.StatusOK))
|
||||
res, err := c.get(ctx, c.directoryURL(), wantStatus(http.StatusOK))
|
||||
if err != nil {
|
||||
return Directory{}, err
|
||||
}
|
||||
|
@ -161,6 +161,13 @@ func (c *Client) Discover(ctx context.Context) (Directory, error) {
|
|||
return *c.dir, nil
|
||||
}
|
||||
|
||||
func (c *Client) directoryURL() string {
|
||||
if c.DirectoryURL != "" {
|
||||
return c.DirectoryURL
|
||||
}
|
||||
return LetsEncryptURL
|
||||
}
|
||||
|
||||
// CreateCert requests a new certificate using the Certificate Signing Request csr encoded in DER format.
|
||||
// The exp argument indicates the desired certificate validity duration. CA may issue a certificate
|
||||
// with a different duration.
|
||||
|
@ -319,6 +326,20 @@ func (c *Client) UpdateReg(ctx context.Context, a *Account) (*Account, error) {
|
|||
// a valid authorization (Authorization.Status is StatusValid). If so, the caller
|
||||
// need not fulfill any challenge and can proceed to requesting a certificate.
|
||||
func (c *Client) Authorize(ctx context.Context, domain string) (*Authorization, error) {
|
||||
return c.authorize(ctx, "dns", domain)
|
||||
}
|
||||
|
||||
// AuthorizeIP is the same as Authorize but requests IP address authorization.
|
||||
// Clients which successfully obtain such authorization may request to issue
|
||||
// a certificate for IP addresses.
|
||||
//
|
||||
// See the ACME spec extension for more details about IP address identifiers:
|
||||
// https://tools.ietf.org/html/draft-ietf-acme-ip.
|
||||
func (c *Client) AuthorizeIP(ctx context.Context, ipaddr string) (*Authorization, error) {
|
||||
return c.authorize(ctx, "ip", ipaddr)
|
||||
}
|
||||
|
||||
func (c *Client) authorize(ctx context.Context, typ, val string) (*Authorization, error) {
|
||||
if _, err := c.Discover(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -332,7 +353,7 @@ func (c *Client) Authorize(ctx context.Context, domain string) (*Authorization,
|
|||
Identifier authzID `json:"identifier"`
|
||||
}{
|
||||
Resource: "new-authz",
|
||||
Identifier: authzID{Type: "dns", Value: domain},
|
||||
Identifier: authzID{Type: typ, Value: val},
|
||||
}
|
||||
res, err := c.post(ctx, c.Key, c.dir.AuthzURL, req, wantStatus(http.StatusCreated))
|
||||
if err != nil {
|
||||
|
@ -693,12 +714,18 @@ func (c *Client) doReg(ctx context.Context, url string, typ string, acct *Accoun
|
|||
}
|
||||
|
||||
// popNonce returns a nonce value previously stored with c.addNonce
|
||||
// or fetches a fresh one from the given URL.
|
||||
// or fetches a fresh one from a URL by issuing a HEAD request.
|
||||
// It first tries c.directoryURL() and then the provided url if the former fails.
|
||||
func (c *Client) popNonce(ctx context.Context, url string) (string, error) {
|
||||
c.noncesMu.Lock()
|
||||
defer c.noncesMu.Unlock()
|
||||
if len(c.nonces) == 0 {
|
||||
return c.fetchNonce(ctx, url)
|
||||
dirURL := c.directoryURL()
|
||||
v, err := c.fetchNonce(ctx, dirURL)
|
||||
if err != nil && url != dirURL {
|
||||
v, err = c.fetchNonce(ctx, url)
|
||||
}
|
||||
return v, err
|
||||
}
|
||||
var nonce string
|
||||
for nonce = range c.nonces {
|
||||
|
|
29
vendor/golang.org/x/crypto/acme/jws.go
generated
vendored
29
vendor/golang.org/x/crypto/acme/jws.go
generated
vendored
|
@ -25,7 +25,7 @@ func jwsEncodeJSON(claimset interface{}, key crypto.Signer, nonce string) ([]byt
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
alg, sha := jwsHasher(key)
|
||||
alg, sha := jwsHasher(key.Public())
|
||||
if alg == "" || !sha.Available() {
|
||||
return nil, ErrUnsupportedKey
|
||||
}
|
||||
|
@ -97,13 +97,16 @@ func jwkEncode(pub crypto.PublicKey) (string, error) {
|
|||
}
|
||||
|
||||
// jwsSign signs the digest using the given key.
|
||||
// It returns ErrUnsupportedKey if the key type is unknown.
|
||||
// The hash is used only for RSA keys.
|
||||
// The hash is unused for ECDSA keys.
|
||||
//
|
||||
// Note: non-stdlib crypto.Signer implementations are expected to return
|
||||
// the signature in the format as specified in RFC7518.
|
||||
// See https://tools.ietf.org/html/rfc7518 for more details.
|
||||
func jwsSign(key crypto.Signer, hash crypto.Hash, digest []byte) ([]byte, error) {
|
||||
switch key := key.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
return key.Sign(rand.Reader, digest, hash)
|
||||
case *ecdsa.PrivateKey:
|
||||
if key, ok := key.(*ecdsa.PrivateKey); ok {
|
||||
// The key.Sign method of ecdsa returns ASN1-encoded signature.
|
||||
// So, we use the package Sign function instead
|
||||
// to get R and S values directly and format the result accordingly.
|
||||
r, s, err := ecdsa.Sign(rand.Reader, key, digest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -118,18 +121,18 @@ func jwsSign(key crypto.Signer, hash crypto.Hash, digest []byte) ([]byte, error)
|
|||
copy(sig[size*2-len(sb):], sb)
|
||||
return sig, nil
|
||||
}
|
||||
return nil, ErrUnsupportedKey
|
||||
return key.Sign(rand.Reader, digest, hash)
|
||||
}
|
||||
|
||||
// jwsHasher indicates suitable JWS algorithm name and a hash function
|
||||
// to use for signing a digest with the provided key.
|
||||
// It returns ("", 0) if the key is not supported.
|
||||
func jwsHasher(key crypto.Signer) (string, crypto.Hash) {
|
||||
switch key := key.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
func jwsHasher(pub crypto.PublicKey) (string, crypto.Hash) {
|
||||
switch pub := pub.(type) {
|
||||
case *rsa.PublicKey:
|
||||
return "RS256", crypto.SHA256
|
||||
case *ecdsa.PrivateKey:
|
||||
switch key.Params().Name {
|
||||
case *ecdsa.PublicKey:
|
||||
switch pub.Params().Name {
|
||||
case "P-256":
|
||||
return "ES256", crypto.SHA256
|
||||
case "P-384":
|
||||
|
|
8
vendor/golang.org/x/crypto/blowfish/cipher.go
generated
vendored
8
vendor/golang.org/x/crypto/blowfish/cipher.go
generated
vendored
|
@ -3,6 +3,14 @@
|
|||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package blowfish implements Bruce Schneier's Blowfish encryption algorithm.
|
||||
//
|
||||
// Blowfish is a legacy cipher and its short block size makes it vulnerable to
|
||||
// birthday bound attacks (see https://sweet32.info). It should only be used
|
||||
// where compatibility with legacy systems, not security, is the goal.
|
||||
//
|
||||
// Deprecated: any new system should use AES (from crypto/aes, if necessary in
|
||||
// an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
|
||||
// golang.org/x/crypto/chacha20poly1305).
|
||||
package blowfish // import "golang.org/x/crypto/blowfish"
|
||||
|
||||
// The code is a port of Bruce Schneier's C implementation.
|
||||
|
|
8
vendor/golang.org/x/crypto/curve25519/const_amd64.h
generated
vendored
8
vendor/golang.org/x/crypto/curve25519/const_amd64.h
generated
vendored
|
@ -1,8 +0,0 @@
|
|||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This code was translated into a form compatible with 6a from the public
|
||||
// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
|
||||
|
||||
#define REDMASK51 0x0007FFFFFFFFFFFF
|
20
vendor/golang.org/x/crypto/curve25519/const_amd64.s
generated
vendored
20
vendor/golang.org/x/crypto/curve25519/const_amd64.s
generated
vendored
|
@ -1,20 +0,0 @@
|
|||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This code was translated into a form compatible with 6a from the public
|
||||
// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
|
||||
|
||||
// +build amd64,!gccgo,!appengine
|
||||
|
||||
// These constants cannot be encoded in non-MOVQ immediates.
|
||||
// We access them directly from memory instead.
|
||||
|
||||
DATA ·_121666_213(SB)/8, $996687872
|
||||
GLOBL ·_121666_213(SB), 8, $8
|
||||
|
||||
DATA ·_2P0(SB)/8, $0xFFFFFFFFFFFDA
|
||||
GLOBL ·_2P0(SB), 8, $8
|
||||
|
||||
DATA ·_2P1234(SB)/8, $0xFFFFFFFFFFFFE
|
||||
GLOBL ·_2P1234(SB), 8, $8
|
65
vendor/golang.org/x/crypto/curve25519/cswap_amd64.s
generated
vendored
65
vendor/golang.org/x/crypto/curve25519/cswap_amd64.s
generated
vendored
|
@ -1,65 +0,0 @@
|
|||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build amd64,!gccgo,!appengine
|
||||
|
||||
// func cswap(inout *[4][5]uint64, v uint64)
|
||||
TEXT ·cswap(SB),7,$0
|
||||
MOVQ inout+0(FP),DI
|
||||
MOVQ v+8(FP),SI
|
||||
|
||||
SUBQ $1, SI
|
||||
NOTQ SI
|
||||
MOVQ SI, X15
|
||||
PSHUFD $0x44, X15, X15
|
||||
|
||||
MOVOU 0(DI), X0
|
||||
MOVOU 16(DI), X2
|
||||
MOVOU 32(DI), X4
|
||||
MOVOU 48(DI), X6
|
||||
MOVOU 64(DI), X8
|
||||
MOVOU 80(DI), X1
|
||||
MOVOU 96(DI), X3
|
||||
MOVOU 112(DI), X5
|
||||
MOVOU 128(DI), X7
|
||||
MOVOU 144(DI), X9
|
||||
|
||||
MOVO X1, X10
|
||||
MOVO X3, X11
|
||||
MOVO X5, X12
|
||||
MOVO X7, X13
|
||||
MOVO X9, X14
|
||||
|
||||
PXOR X0, X10
|
||||
PXOR X2, X11
|
||||
PXOR X4, X12
|
||||
PXOR X6, X13
|
||||
PXOR X8, X14
|
||||
PAND X15, X10
|
||||
PAND X15, X11
|
||||
PAND X15, X12
|
||||
PAND X15, X13
|
||||
PAND X15, X14
|
||||
PXOR X10, X0
|
||||
PXOR X10, X1
|
||||
PXOR X11, X2
|
||||
PXOR X11, X3
|
||||
PXOR X12, X4
|
||||
PXOR X12, X5
|
||||
PXOR X13, X6
|
||||
PXOR X13, X7
|
||||
PXOR X14, X8
|
||||
PXOR X14, X9
|
||||
|
||||
MOVOU X0, 0(DI)
|
||||
MOVOU X2, 16(DI)
|
||||
MOVOU X4, 32(DI)
|
||||
MOVOU X6, 48(DI)
|
||||
MOVOU X8, 64(DI)
|
||||
MOVOU X1, 80(DI)
|
||||
MOVOU X3, 96(DI)
|
||||
MOVOU X5, 112(DI)
|
||||
MOVOU X7, 128(DI)
|
||||
MOVOU X9, 144(DI)
|
||||
RET
|
834
vendor/golang.org/x/crypto/curve25519/curve25519.go
generated
vendored
834
vendor/golang.org/x/crypto/curve25519/curve25519.go
generated
vendored
|
@ -1,834 +0,0 @@
|
|||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// We have an implementation in amd64 assembly so this code is only run on
|
||||
// non-amd64 platforms. The amd64 assembly does not support gccgo.
|
||||
// +build !amd64 gccgo appengine
|
||||
|
||||
package curve25519
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
// This code is a port of the public domain, "ref10" implementation of
|
||||
// curve25519 from SUPERCOP 20130419 by D. J. Bernstein.
|
||||
|
||||
// fieldElement represents an element of the field GF(2^255 - 19). An element
|
||||
// t, entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77
|
||||
// t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on
|
||||
// context.
|
||||
type fieldElement [10]int32
|
||||
|
||||
func feZero(fe *fieldElement) {
|
||||
for i := range fe {
|
||||
fe[i] = 0
|
||||
}
|
||||
}
|
||||
|
||||
func feOne(fe *fieldElement) {
|
||||
feZero(fe)
|
||||
fe[0] = 1
|
||||
}
|
||||
|
||||
func feAdd(dst, a, b *fieldElement) {
|
||||
for i := range dst {
|
||||
dst[i] = a[i] + b[i]
|
||||
}
|
||||
}
|
||||
|
||||
func feSub(dst, a, b *fieldElement) {
|
||||
for i := range dst {
|
||||
dst[i] = a[i] - b[i]
|
||||
}
|
||||
}
|
||||
|
||||
func feCopy(dst, src *fieldElement) {
|
||||
for i := range dst {
|
||||
dst[i] = src[i]
|
||||
}
|
||||
}
|
||||
|
||||
// feCSwap replaces (f,g) with (g,f) if b == 1; replaces (f,g) with (f,g) if b == 0.
|
||||
//
|
||||
// Preconditions: b in {0,1}.
|
||||
func feCSwap(f, g *fieldElement, b int32) {
|
||||
b = -b
|
||||
for i := range f {
|
||||
t := b & (f[i] ^ g[i])
|
||||
f[i] ^= t
|
||||
g[i] ^= t
|
||||
}
|
||||
}
|
||||
|
||||
// load3 reads a 24-bit, little-endian value from in.
|
||||
func load3(in []byte) int64 {
|
||||
var r int64
|
||||
r = int64(in[0])
|
||||
r |= int64(in[1]) << 8
|
||||
r |= int64(in[2]) << 16
|
||||
return r
|
||||
}
|
||||
|
||||
// load4 reads a 32-bit, little-endian value from in.
|
||||
func load4(in []byte) int64 {
|
||||
return int64(binary.LittleEndian.Uint32(in))
|
||||
}
|
||||
|
||||
func feFromBytes(dst *fieldElement, src *[32]byte) {
|
||||
h0 := load4(src[:])
|
||||
h1 := load3(src[4:]) << 6
|
||||
h2 := load3(src[7:]) << 5
|
||||
h3 := load3(src[10:]) << 3
|
||||
h4 := load3(src[13:]) << 2
|
||||
h5 := load4(src[16:])
|
||||
h6 := load3(src[20:]) << 7
|
||||
h7 := load3(src[23:]) << 5
|
||||
h8 := load3(src[26:]) << 4
|
||||
h9 := load3(src[29:]) << 2
|
||||
|
||||
var carry [10]int64
|
||||
carry[9] = (h9 + 1<<24) >> 25
|
||||
h0 += carry[9] * 19
|
||||
h9 -= carry[9] << 25
|
||||
carry[1] = (h1 + 1<<24) >> 25
|
||||
h2 += carry[1]
|
||||
h1 -= carry[1] << 25
|
||||
carry[3] = (h3 + 1<<24) >> 25
|
||||
h4 += carry[3]
|
||||
h3 -= carry[3] << 25
|
||||
carry[5] = (h5 + 1<<24) >> 25
|
||||
h6 += carry[5]
|
||||
h5 -= carry[5] << 25
|
||||
carry[7] = (h7 + 1<<24) >> 25
|
||||
h8 += carry[7]
|
||||
h7 -= carry[7] << 25
|
||||
|
||||
carry[0] = (h0 + 1<<25) >> 26
|
||||
h1 += carry[0]
|
||||
h0 -= carry[0] << 26
|
||||
carry[2] = (h2 + 1<<25) >> 26
|
||||
h3 += carry[2]
|
||||
h2 -= carry[2] << 26
|
||||
carry[4] = (h4 + 1<<25) >> 26
|
||||
h5 += carry[4]
|
||||
h4 -= carry[4] << 26
|
||||
carry[6] = (h6 + 1<<25) >> 26
|
||||
h7 += carry[6]
|
||||
h6 -= carry[6] << 26
|
||||
carry[8] = (h8 + 1<<25) >> 26
|
||||
h9 += carry[8]
|
||||
h8 -= carry[8] << 26
|
||||
|
||||
dst[0] = int32(h0)
|
||||
dst[1] = int32(h1)
|
||||
dst[2] = int32(h2)
|
||||
dst[3] = int32(h3)
|
||||
dst[4] = int32(h4)
|
||||
dst[5] = int32(h5)
|
||||
dst[6] = int32(h6)
|
||||
dst[7] = int32(h7)
|
||||
dst[8] = int32(h8)
|
||||
dst[9] = int32(h9)
|
||||
}
|
||||
|
||||
// feToBytes marshals h to s.
|
||||
// Preconditions:
|
||||
// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||
//
|
||||
// Write p=2^255-19; q=floor(h/p).
|
||||
// Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
|
||||
//
|
||||
// Proof:
|
||||
// Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
|
||||
// Also have |h-2^230 h9|<2^230 so |19 2^(-255)(h-2^230 h9)|<1/4.
|
||||
//
|
||||
// Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
|
||||
// Then 0<y<1.
|
||||
//
|
||||
// Write r=h-pq.
|
||||
// Have 0<=r<=p-1=2^255-20.
|
||||
// Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1.
|
||||
//
|
||||
// Write x=r+19(2^-255)r+y.
|
||||
// Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.
|
||||
//
|
||||
// Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
|
||||
// so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q.
|
||||
func feToBytes(s *[32]byte, h *fieldElement) {
|
||||
var carry [10]int32
|
||||
|
||||
q := (19*h[9] + (1 << 24)) >> 25
|
||||
q = (h[0] + q) >> 26
|
||||
q = (h[1] + q) >> 25
|
||||
q = (h[2] + q) >> 26
|
||||
q = (h[3] + q) >> 25
|
||||
q = (h[4] + q) >> 26
|
||||
q = (h[5] + q) >> 25
|
||||
q = (h[6] + q) >> 26
|
||||
q = (h[7] + q) >> 25
|
||||
q = (h[8] + q) >> 26
|
||||
q = (h[9] + q) >> 25
|
||||
|
||||
// Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20.
|
||||
h[0] += 19 * q
|
||||
// Goal: Output h-2^255 q, which is between 0 and 2^255-20.
|
||||
|
||||
carry[0] = h[0] >> 26
|
||||
h[1] += carry[0]
|
||||
h[0] -= carry[0] << 26
|
||||
carry[1] = h[1] >> 25
|
||||
h[2] += carry[1]
|
||||
h[1] -= carry[1] << 25
|
||||
carry[2] = h[2] >> 26
|
||||
h[3] += carry[2]
|
||||
h[2] -= carry[2] << 26
|
||||
carry[3] = h[3] >> 25
|
||||
h[4] += carry[3]
|
||||
h[3] -= carry[3] << 25
|
||||
carry[4] = h[4] >> 26
|
||||
h[5] += carry[4]
|
||||
h[4] -= carry[4] << 26
|
||||
carry[5] = h[5] >> 25
|
||||
h[6] += carry[5]
|
||||
h[5] -= carry[5] << 25
|
||||
carry[6] = h[6] >> 26
|
||||
h[7] += carry[6]
|
||||
h[6] -= carry[6] << 26
|
||||
carry[7] = h[7] >> 25
|
||||
h[8] += carry[7]
|
||||
h[7] -= carry[7] << 25
|
||||
carry[8] = h[8] >> 26
|
||||
h[9] += carry[8]
|
||||
h[8] -= carry[8] << 26
|
||||
carry[9] = h[9] >> 25
|
||||
h[9] -= carry[9] << 25
|
||||
// h10 = carry9
|
||||
|
||||
// Goal: Output h[0]+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
|
||||
// Have h[0]+...+2^230 h[9] between 0 and 2^255-1;
|
||||
// evidently 2^255 h10-2^255 q = 0.
|
||||
// Goal: Output h[0]+...+2^230 h[9].
|
||||
|
||||
s[0] = byte(h[0] >> 0)
|
||||
s[1] = byte(h[0] >> 8)
|
||||
s[2] = byte(h[0] >> 16)
|
||||
s[3] = byte((h[0] >> 24) | (h[1] << 2))
|
||||
s[4] = byte(h[1] >> 6)
|
||||
s[5] = byte(h[1] >> 14)
|
||||
s[6] = byte((h[1] >> 22) | (h[2] << 3))
|
||||
s[7] = byte(h[2] >> 5)
|
||||
s[8] = byte(h[2] >> 13)
|
||||
s[9] = byte((h[2] >> 21) | (h[3] << 5))
|
||||
s[10] = byte(h[3] >> 3)
|
||||
s[11] = byte(h[3] >> 11)
|
||||
s[12] = byte((h[3] >> 19) | (h[4] << 6))
|
||||
s[13] = byte(h[4] >> 2)
|
||||
s[14] = byte(h[4] >> 10)
|
||||
s[15] = byte(h[4] >> 18)
|
||||
s[16] = byte(h[5] >> 0)
|
||||
s[17] = byte(h[5] >> 8)
|
||||
s[18] = byte(h[5] >> 16)
|
||||
s[19] = byte((h[5] >> 24) | (h[6] << 1))
|
||||
s[20] = byte(h[6] >> 7)
|
||||
s[21] = byte(h[6] >> 15)
|
||||
s[22] = byte((h[6] >> 23) | (h[7] << 3))
|
||||
s[23] = byte(h[7] >> 5)
|
||||
s[24] = byte(h[7] >> 13)
|
||||
s[25] = byte((h[7] >> 21) | (h[8] << 4))
|
||||
s[26] = byte(h[8] >> 4)
|
||||
s[27] = byte(h[8] >> 12)
|
||||
s[28] = byte((h[8] >> 20) | (h[9] << 6))
|
||||
s[29] = byte(h[9] >> 2)
|
||||
s[30] = byte(h[9] >> 10)
|
||||
s[31] = byte(h[9] >> 18)
|
||||
}
|
||||
|
||||
// feMul calculates h = f * g
|
||||
// Can overlap h with f or g.
|
||||
//
|
||||
// Preconditions:
|
||||
// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||
// |g| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||
//
|
||||
// Postconditions:
|
||||
// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||
//
|
||||
// Notes on implementation strategy:
|
||||
//
|
||||
// Using schoolbook multiplication.
|
||||
// Karatsuba would save a little in some cost models.
|
||||
//
|
||||
// Most multiplications by 2 and 19 are 32-bit precomputations;
|
||||
// cheaper than 64-bit postcomputations.
|
||||
//
|
||||
// There is one remaining multiplication by 19 in the carry chain;
|
||||
// one *19 precomputation can be merged into this,
|
||||
// but the resulting data flow is considerably less clean.
|
||||
//
|
||||
// There are 12 carries below.
|
||||
// 10 of them are 2-way parallelizable and vectorizable.
|
||||
// Can get away with 11 carries, but then data flow is much deeper.
|
||||
//
|
||||
// With tighter constraints on inputs can squeeze carries into int32.
|
||||
func feMul(h, f, g *fieldElement) {
|
||||
f0 := f[0]
|
||||
f1 := f[1]
|
||||
f2 := f[2]
|
||||
f3 := f[3]
|
||||
f4 := f[4]
|
||||
f5 := f[5]
|
||||
f6 := f[6]
|
||||
f7 := f[7]
|
||||
f8 := f[8]
|
||||
f9 := f[9]
|
||||
g0 := g[0]
|
||||
g1 := g[1]
|
||||
g2 := g[2]
|
||||
g3 := g[3]
|
||||
g4 := g[4]
|
||||
g5 := g[5]
|
||||
g6 := g[6]
|
||||
g7 := g[7]
|
||||
g8 := g[8]
|
||||
g9 := g[9]
|
||||
g1_19 := 19 * g1 // 1.4*2^29
|
||||
g2_19 := 19 * g2 // 1.4*2^30; still ok
|
||||
g3_19 := 19 * g3
|
||||
g4_19 := 19 * g4
|
||||
g5_19 := 19 * g5
|
||||
g6_19 := 19 * g6
|
||||
g7_19 := 19 * g7
|
||||
g8_19 := 19 * g8
|
||||
g9_19 := 19 * g9
|
||||
f1_2 := 2 * f1
|
||||
f3_2 := 2 * f3
|
||||
f5_2 := 2 * f5
|
||||
f7_2 := 2 * f7
|
||||
f9_2 := 2 * f9
|
||||
f0g0 := int64(f0) * int64(g0)
|
||||
f0g1 := int64(f0) * int64(g1)
|
||||
f0g2 := int64(f0) * int64(g2)
|
||||
f0g3 := int64(f0) * int64(g3)
|
||||
f0g4 := int64(f0) * int64(g4)
|
||||
f0g5 := int64(f0) * int64(g5)
|
||||
f0g6 := int64(f0) * int64(g6)
|
||||
f0g7 := int64(f0) * int64(g7)
|
||||
f0g8 := int64(f0) * int64(g8)
|
||||
f0g9 := int64(f0) * int64(g9)
|
||||
f1g0 := int64(f1) * int64(g0)
|
||||
f1g1_2 := int64(f1_2) * int64(g1)
|
||||
f1g2 := int64(f1) * int64(g2)
|
||||
f1g3_2 := int64(f1_2) * int64(g3)
|
||||
f1g4 := int64(f1) * int64(g4)
|
||||
f1g5_2 := int64(f1_2) * int64(g5)
|
||||
f1g6 := int64(f1) * int64(g6)
|
||||
f1g7_2 := int64(f1_2) * int64(g7)
|
||||
f1g8 := int64(f1) * int64(g8)
|
||||
f1g9_38 := int64(f1_2) * int64(g9_19)
|
||||
f2g0 := int64(f2) * int64(g0)
|
||||
f2g1 := int64(f2) * int64(g1)
|
||||
f2g2 := int64(f2) * int64(g2)
|
||||
f2g3 := int64(f2) * int64(g3)
|
||||
f2g4 := int64(f2) * int64(g4)
|
||||
f2g5 := int64(f2) * int64(g5)
|
||||
f2g6 := int64(f2) * int64(g6)
|
||||
f2g7 := int64(f2) * int64(g7)
|
||||
f2g8_19 := int64(f2) * int64(g8_19)
|
||||
f2g9_19 := int64(f2) * int64(g9_19)
|
||||
f3g0 := int64(f3) * int64(g0)
|
||||
f3g1_2 := int64(f3_2) * int64(g1)
|
||||
f3g2 := int64(f3) * int64(g2)
|
||||
f3g3_2 := int64(f3_2) * int64(g3)
|
||||
f3g4 := int64(f3) * int64(g4)
|
||||
f3g5_2 := int64(f3_2) * int64(g5)
|
||||
f3g6 := int64(f3) * int64(g6)
|
||||
f3g7_38 := int64(f3_2) * int64(g7_19)
|
||||
f3g8_19 := int64(f3) * int64(g8_19)
|
||||
f3g9_38 := int64(f3_2) * int64(g9_19)
|
||||
f4g0 := int64(f4) * int64(g0)
|
||||
f4g1 := int64(f4) * int64(g1)
|
||||
f4g2 := int64(f4) * int64(g2)
|
||||
f4g3 := int64(f4) * int64(g3)
|
||||
f4g4 := int64(f4) * int64(g4)
|
||||
f4g5 := int64(f4) * int64(g5)
|
||||
f4g6_19 := int64(f4) * int64(g6_19)
|
||||
f4g7_19 := int64(f4) * int64(g7_19)
|
||||
f4g8_19 := int64(f4) * int64(g8_19)
|
||||
f4g9_19 := int64(f4) * int64(g9_19)
|
||||
f5g0 := int64(f5) * int64(g0)
|
||||
f5g1_2 := int64(f5_2) * int64(g1)
|
||||
f5g2 := int64(f5) * int64(g2)
|
||||
f5g3_2 := int64(f5_2) * int64(g3)
|
||||
f5g4 := int64(f5) * int64(g4)
|
||||
f5g5_38 := int64(f5_2) * int64(g5_19)
|
||||
f5g6_19 := int64(f5) * int64(g6_19)
|
||||
f5g7_38 := int64(f5_2) * int64(g7_19)
|
||||
f5g8_19 := int64(f5) * int64(g8_19)
|
||||
f5g9_38 := int64(f5_2) * int64(g9_19)
|
||||
f6g0 := int64(f6) * int64(g0)
|
||||
f6g1 := int64(f6) * int64(g1)
|
||||
f6g2 := int64(f6) * int64(g2)
|
||||
f6g3 := int64(f6) * int64(g3)
|
||||
f6g4_19 := int64(f6) * int64(g4_19)
|
||||
f6g5_19 := int64(f6) * int64(g5_19)
|
||||
f6g6_19 := int64(f6) * int64(g6_19)
|
||||
f6g7_19 := int64(f6) * int64(g7_19)
|
||||
f6g8_19 := int64(f6) * int64(g8_19)
|
||||
f6g9_19 := int64(f6) * int64(g9_19)
|
||||
f7g0 := int64(f7) * int64(g0)
|
||||
f7g1_2 := int64(f7_2) * int64(g1)
|
||||
f7g2 := int64(f7) * int64(g2)
|
||||
f7g3_38 := int64(f7_2) * int64(g3_19)
|
||||
f7g4_19 := int64(f7) * int64(g4_19)
|
||||
f7g5_38 := int64(f7_2) * int64(g5_19)
|
||||
f7g6_19 := int64(f7) * int64(g6_19)
|
||||
f7g7_38 := int64(f7_2) * int64(g7_19)
|
||||
f7g8_19 := int64(f7) * int64(g8_19)
|
||||
f7g9_38 := int64(f7_2) * int64(g9_19)
|
||||
f8g0 := int64(f8) * int64(g0)
|
||||
f8g1 := int64(f8) * int64(g1)
|
||||
f8g2_19 := int64(f8) * int64(g2_19)
|
||||
f8g3_19 := int64(f8) * int64(g3_19)
|
||||
f8g4_19 := int64(f8) * int64(g4_19)
|
||||
f8g5_19 := int64(f8) * int64(g5_19)
|
||||
f8g6_19 := int64(f8) * int64(g6_19)
|
||||
f8g7_19 := int64(f8) * int64(g7_19)
|
||||
f8g8_19 := int64(f8) * int64(g8_19)
|
||||
f8g9_19 := int64(f8) * int64(g9_19)
|
||||
f9g0 := int64(f9) * int64(g0)
|
||||
f9g1_38 := int64(f9_2) * int64(g1_19)
|
||||
f9g2_19 := int64(f9) * int64(g2_19)
|
||||
f9g3_38 := int64(f9_2) * int64(g3_19)
|
||||
f9g4_19 := int64(f9) * int64(g4_19)
|
||||
f9g5_38 := int64(f9_2) * int64(g5_19)
|
||||
f9g6_19 := int64(f9) * int64(g6_19)
|
||||
f9g7_38 := int64(f9_2) * int64(g7_19)
|
||||
f9g8_19 := int64(f9) * int64(g8_19)
|
||||
f9g9_38 := int64(f9_2) * int64(g9_19)
|
||||
h0 := f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38
|
||||
h1 := f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19
|
||||
h2 := f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38
|
||||
h3 := f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19
|
||||
h4 := f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38
|
||||
h5 := f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19
|
||||
h6 := f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38
|
||||
h7 := f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19
|
||||
h8 := f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38
|
||||
h9 := f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0
|
||||
var carry [10]int64
|
||||
|
||||
// |h0| <= (1.1*1.1*2^52*(1+19+19+19+19)+1.1*1.1*2^50*(38+38+38+38+38))
|
||||
// i.e. |h0| <= 1.2*2^59; narrower ranges for h2, h4, h6, h8
|
||||
// |h1| <= (1.1*1.1*2^51*(1+1+19+19+19+19+19+19+19+19))
|
||||
// i.e. |h1| <= 1.5*2^58; narrower ranges for h3, h5, h7, h9
|
||||
|
||||
carry[0] = (h0 + (1 << 25)) >> 26
|
||||
h1 += carry[0]
|
||||
h0 -= carry[0] << 26
|
||||
carry[4] = (h4 + (1 << 25)) >> 26
|
||||
h5 += carry[4]
|
||||
h4 -= carry[4] << 26
|
||||
// |h0| <= 2^25
|
||||
// |h4| <= 2^25
|
||||
// |h1| <= 1.51*2^58
|
||||
// |h5| <= 1.51*2^58
|
||||
|
||||
carry[1] = (h1 + (1 << 24)) >> 25
|
||||
h2 += carry[1]
|
||||
h1 -= carry[1] << 25
|
||||
carry[5] = (h5 + (1 << 24)) >> 25
|
||||
h6 += carry[5]
|
||||
h5 -= carry[5] << 25
|
||||
// |h1| <= 2^24; from now on fits into int32
|
||||
// |h5| <= 2^24; from now on fits into int32
|
||||
// |h2| <= 1.21*2^59
|
||||
// |h6| <= 1.21*2^59
|
||||
|
||||
carry[2] = (h2 + (1 << 25)) >> 26
|
||||
h3 += carry[2]
|
||||
h2 -= carry[2] << 26
|
||||
carry[6] = (h6 + (1 << 25)) >> 26
|
||||
h7 += carry[6]
|
||||
h6 -= carry[6] << 26
|
||||
// |h2| <= 2^25; from now on fits into int32 unchanged
|
||||
// |h6| <= 2^25; from now on fits into int32 unchanged
|
||||
// |h3| <= 1.51*2^58
|
||||
// |h7| <= 1.51*2^58
|
||||
|
||||
carry[3] = (h3 + (1 << 24)) >> 25
|
||||
h4 += carry[3]
|
||||
h3 -= carry[3] << 25
|
||||
carry[7] = (h7 + (1 << 24)) >> 25
|
||||
h8 += carry[7]
|
||||
h7 -= carry[7] << 25
|
||||
// |h3| <= 2^24; from now on fits into int32 unchanged
|
||||
// |h7| <= 2^24; from now on fits into int32 unchanged
|
||||
// |h4| <= 1.52*2^33
|
||||
// |h8| <= 1.52*2^33
|
||||
|
||||
carry[4] = (h4 + (1 << 25)) >> 26
|
||||
h5 += carry[4]
|
||||
h4 -= carry[4] << 26
|
||||
carry[8] = (h8 + (1 << 25)) >> 26
|
||||
h9 += carry[8]
|
||||
h8 -= carry[8] << 26
|
||||
// |h4| <= 2^25; from now on fits into int32 unchanged
|
||||
// |h8| <= 2^25; from now on fits into int32 unchanged
|
||||
// |h5| <= 1.01*2^24
|
||||
// |h9| <= 1.51*2^58
|
||||
|
||||
carry[9] = (h9 + (1 << 24)) >> 25
|
||||
h0 += carry[9] * 19
|
||||
h9 -= carry[9] << 25
|
||||
// |h9| <= 2^24; from now on fits into int32 unchanged
|
||||
// |h0| <= 1.8*2^37
|
||||
|
||||
carry[0] = (h0 + (1 << 25)) >> 26
|
||||
h1 += carry[0]
|
||||
h0 -= carry[0] << 26
|
||||
// |h0| <= 2^25; from now on fits into int32 unchanged
|
||||
// |h1| <= 1.01*2^24
|
||||
|
||||
h[0] = int32(h0)
|
||||
h[1] = int32(h1)
|
||||
h[2] = int32(h2)
|
||||
h[3] = int32(h3)
|
||||
h[4] = int32(h4)
|
||||
h[5] = int32(h5)
|
||||
h[6] = int32(h6)
|
||||
h[7] = int32(h7)
|
||||
h[8] = int32(h8)
|
||||
h[9] = int32(h9)
|
||||
}
|
||||
|
||||
// feSquare calculates h = f*f. Can overlap h with f.
|
||||
//
|
||||
// Preconditions:
|
||||
// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||
//
|
||||
// Postconditions:
|
||||
// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||
func feSquare(h, f *fieldElement) {
|
||||
f0 := f[0]
|
||||
f1 := f[1]
|
||||
f2 := f[2]
|
||||
f3 := f[3]
|
||||
f4 := f[4]
|
||||
f5 := f[5]
|
||||
f6 := f[6]
|
||||
f7 := f[7]
|
||||
f8 := f[8]
|
||||
f9 := f[9]
|
||||
f0_2 := 2 * f0
|
||||
f1_2 := 2 * f1
|
||||
f2_2 := 2 * f2
|
||||
f3_2 := 2 * f3
|
||||
f4_2 := 2 * f4
|
||||
f5_2 := 2 * f5
|
||||
f6_2 := 2 * f6
|
||||
f7_2 := 2 * f7
|
||||
f5_38 := 38 * f5 // 1.31*2^30
|
||||
f6_19 := 19 * f6 // 1.31*2^30
|
||||
f7_38 := 38 * f7 // 1.31*2^30
|
||||
f8_19 := 19 * f8 // 1.31*2^30
|
||||
f9_38 := 38 * f9 // 1.31*2^30
|
||||
f0f0 := int64(f0) * int64(f0)
|
||||
f0f1_2 := int64(f0_2) * int64(f1)
|
||||
f0f2_2 := int64(f0_2) * int64(f2)
|
||||
f0f3_2 := int64(f0_2) * int64(f3)
|
||||
f0f4_2 := int64(f0_2) * int64(f4)
|
||||
f0f5_2 := int64(f0_2) * int64(f5)
|
||||
f0f6_2 := int64(f0_2) * int64(f6)
|
||||
f0f7_2 := int64(f0_2) * int64(f7)
|
||||
f0f8_2 := int64(f0_2) * int64(f8)
|
||||
f0f9_2 := int64(f0_2) * int64(f9)
|
||||
f1f1_2 := int64(f1_2) * int64(f1)
|
||||
f1f2_2 := int64(f1_2) * int64(f2)
|
||||
f1f3_4 := int64(f1_2) * int64(f3_2)
|
||||
f1f4_2 := int64(f1_2) * int64(f4)
|
||||
f1f5_4 := int64(f1_2) * int64(f5_2)
|
||||
f1f6_2 := int64(f1_2) * int64(f6)
|
||||
f1f7_4 := int64(f1_2) * int64(f7_2)
|
||||
f1f8_2 := int64(f1_2) * int64(f8)
|
||||
f1f9_76 := int64(f1_2) * int64(f9_38)
|
||||
f2f2 := int64(f2) * int64(f2)
|
||||
f2f3_2 := int64(f2_2) * int64(f3)
|
||||
f2f4_2 := int64(f2_2) * int64(f4)
|
||||
f2f5_2 := int64(f2_2) * int64(f5)
|
||||
f2f6_2 := int64(f2_2) * int64(f6)
|
||||
f2f7_2 := int64(f2_2) * int64(f7)
|
||||
f2f8_38 := int64(f2_2) * int64(f8_19)
|
||||
f2f9_38 := int64(f2) * int64(f9_38)
|
||||
f3f3_2 := int64(f3_2) * int64(f3)
|
||||
f3f4_2 := int64(f3_2) * int64(f4)
|
||||
f3f5_4 := int64(f3_2) * int64(f5_2)
|
||||
f3f6_2 := int64(f3_2) * int64(f6)
|
||||
f3f7_76 := int64(f3_2) * int64(f7_38)
|
||||
f3f8_38 := int64(f3_2) * int64(f8_19)
|
||||
f3f9_76 := int64(f3_2) * int64(f9_38)
|
||||
f4f4 := int64(f4) * int64(f4)
|
||||
f4f5_2 := int64(f4_2) * int64(f5)
|
||||
f4f6_38 := int64(f4_2) * int64(f6_19)
|
||||
f4f7_38 := int64(f4) * int64(f7_38)
|
||||
f4f8_38 := int64(f4_2) * int64(f8_19)
|
||||
f4f9_38 := int64(f4) * int64(f9_38)
|
||||
f5f5_38 := int64(f5) * int64(f5_38)
|
||||
f5f6_38 := int64(f5_2) * int64(f6_19)
|
||||
f5f7_76 := int64(f5_2) * int64(f7_38)
|
||||
f5f8_38 := int64(f5_2) * int64(f8_19)
|
||||
f5f9_76 := int64(f5_2) * int64(f9_38)
|
||||
f6f6_19 := int64(f6) * int64(f6_19)
|
||||
f6f7_38 := int64(f6) * int64(f7_38)
|
||||
f6f8_38 := int64(f6_2) * int64(f8_19)
|
||||
f6f9_38 := int64(f6) * int64(f9_38)
|
||||
f7f7_38 := int64(f7) * int64(f7_38)
|
||||
f7f8_38 := int64(f7_2) * int64(f8_19)
|
||||
f7f9_76 := int64(f7_2) * int64(f9_38)
|
||||
f8f8_19 := int64(f8) * int64(f8_19)
|
||||
f8f9_38 := int64(f8) * int64(f9_38)
|
||||
f9f9_38 := int64(f9) * int64(f9_38)
|
||||
h0 := f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38
|
||||
h1 := f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38
|
||||
h2 := f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19
|
||||
h3 := f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38
|
||||
h4 := f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38
|
||||
h5 := f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38
|
||||
h6 := f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19
|
||||
h7 := f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38
|
||||
h8 := f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38
|
||||
h9 := f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2
|
||||
var carry [10]int64
|
||||
|
||||
carry[0] = (h0 + (1 << 25)) >> 26
|
||||
h1 += carry[0]
|
||||
h0 -= carry[0] << 26
|
||||
carry[4] = (h4 + (1 << 25)) >> 26
|
||||
h5 += carry[4]
|
||||
h4 -= carry[4] << 26
|
||||
|
||||
carry[1] = (h1 + (1 << 24)) >> 25
|
||||
h2 += carry[1]
|
||||
h1 -= carry[1] << 25
|
||||
carry[5] = (h5 + (1 << 24)) >> 25
|
||||
h6 += carry[5]
|
||||
h5 -= carry[5] << 25
|
||||
|
||||
carry[2] = (h2 + (1 << 25)) >> 26
|
||||
h3 += carry[2]
|
||||
h2 -= carry[2] << 26
|
||||
carry[6] = (h6 + (1 << 25)) >> 26
|
||||
h7 += carry[6]
|
||||
h6 -= carry[6] << 26
|
||||
|
||||
carry[3] = (h3 + (1 << 24)) >> 25
|
||||
h4 += carry[3]
|
||||
h3 -= carry[3] << 25
|
||||
carry[7] = (h7 + (1 << 24)) >> 25
|
||||
h8 += carry[7]
|
||||
h7 -= carry[7] << 25
|
||||
|
||||
carry[4] = (h4 + (1 << 25)) >> 26
|
||||
h5 += carry[4]
|
||||
h4 -= carry[4] << 26
|
||||
carry[8] = (h8 + (1 << 25)) >> 26
|
||||
h9 += carry[8]
|
||||
h8 -= carry[8] << 26
|
||||
|
||||
carry[9] = (h9 + (1 << 24)) >> 25
|
||||
h0 += carry[9] * 19
|
||||
h9 -= carry[9] << 25
|
||||
|
||||
carry[0] = (h0 + (1 << 25)) >> 26
|
||||
h1 += carry[0]
|
||||
h0 -= carry[0] << 26
|
||||
|
||||
h[0] = int32(h0)
|
||||
h[1] = int32(h1)
|
||||
h[2] = int32(h2)
|
||||
h[3] = int32(h3)
|
||||
h[4] = int32(h4)
|
||||
h[5] = int32(h5)
|
||||
h[6] = int32(h6)
|
||||
h[7] = int32(h7)
|
||||
h[8] = int32(h8)
|
||||
h[9] = int32(h9)
|
||||
}
|
||||
|
||||
// feMul121666 calculates h = f * 121666. Can overlap h with f.
|
||||
//
|
||||
// Preconditions:
|
||||
// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||
//
|
||||
// Postconditions:
|
||||
// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||
func feMul121666(h, f *fieldElement) {
|
||||
h0 := int64(f[0]) * 121666
|
||||
h1 := int64(f[1]) * 121666
|
||||
h2 := int64(f[2]) * 121666
|
||||
h3 := int64(f[3]) * 121666
|
||||
h4 := int64(f[4]) * 121666
|
||||
h5 := int64(f[5]) * 121666
|
||||
h6 := int64(f[6]) * 121666
|
||||
h7 := int64(f[7]) * 121666
|
||||
h8 := int64(f[8]) * 121666
|
||||
h9 := int64(f[9]) * 121666
|
||||
var carry [10]int64
|
||||
|
||||
carry[9] = (h9 + (1 << 24)) >> 25
|
||||
h0 += carry[9] * 19
|
||||
h9 -= carry[9] << 25
|
||||
carry[1] = (h1 + (1 << 24)) >> 25
|
||||
h2 += carry[1]
|
||||
h1 -= carry[1] << 25
|
||||
carry[3] = (h3 + (1 << 24)) >> 25
|
||||
h4 += carry[3]
|
||||
h3 -= carry[3] << 25
|
||||
carry[5] = (h5 + (1 << 24)) >> 25
|
||||
h6 += carry[5]
|
||||
h5 -= carry[5] << 25
|
||||
carry[7] = (h7 + (1 << 24)) >> 25
|
||||
h8 += carry[7]
|
||||
h7 -= carry[7] << 25
|
||||
|
||||
carry[0] = (h0 + (1 << 25)) >> 26
|
||||
h1 += carry[0]
|
||||
h0 -= carry[0] << 26
|
||||
carry[2] = (h2 + (1 << 25)) >> 26
|
||||
h3 += carry[2]
|
||||
h2 -= carry[2] << 26
|
||||
carry[4] = (h4 + (1 << 25)) >> 26
|
||||
h5 += carry[4]
|
||||
h4 -= carry[4] << 26
|
||||
carry[6] = (h6 + (1 << 25)) >> 26
|
||||
h7 += carry[6]
|
||||
h6 -= carry[6] << 26
|
||||
carry[8] = (h8 + (1 << 25)) >> 26
|
||||
h9 += carry[8]
|
||||
h8 -= carry[8] << 26
|
||||
|
||||
h[0] = int32(h0)
|
||||
h[1] = int32(h1)
|
||||
h[2] = int32(h2)
|
||||
h[3] = int32(h3)
|
||||
h[4] = int32(h4)
|
||||
h[5] = int32(h5)
|
||||
h[6] = int32(h6)
|
||||
h[7] = int32(h7)
|
||||
h[8] = int32(h8)
|
||||
h[9] = int32(h9)
|
||||
}
|
||||
|
||||
// feInvert sets out = z^-1.
|
||||
func feInvert(out, z *fieldElement) {
|
||||
var t0, t1, t2, t3 fieldElement
|
||||
var i int
|
||||
|
||||
feSquare(&t0, z)
|
||||
for i = 1; i < 1; i++ {
|
||||
feSquare(&t0, &t0)
|
||||
}
|
||||
feSquare(&t1, &t0)
|
||||
for i = 1; i < 2; i++ {
|
||||
feSquare(&t1, &t1)
|
||||
}
|
||||
feMul(&t1, z, &t1)
|
||||
feMul(&t0, &t0, &t1)
|
||||
feSquare(&t2, &t0)
|
||||
for i = 1; i < 1; i++ {
|
||||
feSquare(&t2, &t2)
|
||||
}
|
||||
feMul(&t1, &t1, &t2)
|
||||
feSquare(&t2, &t1)
|
||||
for i = 1; i < 5; i++ {
|
||||
feSquare(&t2, &t2)
|
||||
}
|
||||
feMul(&t1, &t2, &t1)
|
||||
feSquare(&t2, &t1)
|
||||
for i = 1; i < 10; i++ {
|
||||
feSquare(&t2, &t2)
|
||||
}
|
||||
feMul(&t2, &t2, &t1)
|
||||
feSquare(&t3, &t2)
|
||||
for i = 1; i < 20; i++ {
|
||||
feSquare(&t3, &t3)
|
||||
}
|
||||
feMul(&t2, &t3, &t2)
|
||||
feSquare(&t2, &t2)
|
||||
for i = 1; i < 10; i++ {
|
||||
feSquare(&t2, &t2)
|
||||
}
|
||||
feMul(&t1, &t2, &t1)
|
||||
feSquare(&t2, &t1)
|
||||
for i = 1; i < 50; i++ {
|
||||
feSquare(&t2, &t2)
|
||||
}
|
||||
feMul(&t2, &t2, &t1)
|
||||
feSquare(&t3, &t2)
|
||||
for i = 1; i < 100; i++ {
|
||||
feSquare(&t3, &t3)
|
||||
}
|
||||
feMul(&t2, &t3, &t2)
|
||||
feSquare(&t2, &t2)
|
||||
for i = 1; i < 50; i++ {
|
||||
feSquare(&t2, &t2)
|
||||
}
|
||||
feMul(&t1, &t2, &t1)
|
||||
feSquare(&t1, &t1)
|
||||
for i = 1; i < 5; i++ {
|
||||
feSquare(&t1, &t1)
|
||||
}
|
||||
feMul(out, &t1, &t0)
|
||||
}
|
||||
|
||||
func scalarMult(out, in, base *[32]byte) {
|
||||
var e [32]byte
|
||||
|
||||
copy(e[:], in[:])
|
||||
e[0] &= 248
|
||||
e[31] &= 127
|
||||
e[31] |= 64
|
||||
|
||||
var x1, x2, z2, x3, z3, tmp0, tmp1 fieldElement
|
||||
feFromBytes(&x1, base)
|
||||
feOne(&x2)
|
||||
feCopy(&x3, &x1)
|
||||
feOne(&z3)
|
||||
|
||||
swap := int32(0)
|
||||
for pos := 254; pos >= 0; pos-- {
|
||||
b := e[pos/8] >> uint(pos&7)
|
||||
b &= 1
|
||||
swap ^= int32(b)
|
||||
feCSwap(&x2, &x3, swap)
|
||||
feCSwap(&z2, &z3, swap)
|
||||
swap = int32(b)
|
||||
|
||||
feSub(&tmp0, &x3, &z3)
|
||||
feSub(&tmp1, &x2, &z2)
|
||||
feAdd(&x2, &x2, &z2)
|
||||
feAdd(&z2, &x3, &z3)
|
||||
feMul(&z3, &tmp0, &x2)
|
||||
feMul(&z2, &z2, &tmp1)
|
||||
feSquare(&tmp0, &tmp1)
|
||||
feSquare(&tmp1, &x2)
|
||||
feAdd(&x3, &z3, &z2)
|
||||
feSub(&z2, &z3, &z2)
|
||||
feMul(&x2, &tmp1, &tmp0)
|
||||
feSub(&tmp1, &tmp1, &tmp0)
|
||||
feSquare(&z2, &z2)
|
||||
feMul121666(&z3, &tmp1)
|
||||
feSquare(&x3, &x3)
|
||||
feAdd(&tmp0, &tmp0, &z3)
|
||||
feMul(&z3, &x1, &z2)
|
||||
feMul(&z2, &tmp1, &tmp0)
|
||||
}
|
||||
|
||||
feCSwap(&x2, &x3, swap)
|
||||
feCSwap(&z2, &z3, swap)
|
||||
|
||||
feInvert(&z2, &z2)
|
||||
feMul(&x2, &x2, &z2)
|
||||
feToBytes(out, &x2)
|
||||
}
|
23
vendor/golang.org/x/crypto/curve25519/doc.go
generated
vendored
23
vendor/golang.org/x/crypto/curve25519/doc.go
generated
vendored
|
@ -1,23 +0,0 @@
|
|||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package curve25519 provides an implementation of scalar multiplication on
|
||||
// the elliptic curve known as curve25519. See https://cr.yp.to/ecdh.html
|
||||
package curve25519 // import "golang.org/x/crypto/curve25519"
|
||||
|
||||
// basePoint is the x coordinate of the generator of the curve.
|
||||
var basePoint = [32]byte{9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
|
||||
// ScalarMult sets dst to the product in*base where dst and base are the x
|
||||
// coordinates of group points and all values are in little-endian form.
|
||||
func ScalarMult(dst, in, base *[32]byte) {
|
||||
scalarMult(dst, in, base)
|
||||
}
|
||||
|
||||
// ScalarBaseMult sets dst to the product in*base where dst and base are the x
|
||||
// coordinates of group points, base is the standard generator and all values
|
||||
// are in little-endian form.
|
||||
func ScalarBaseMult(dst, in *[32]byte) {
|
||||
ScalarMult(dst, in, &basePoint)
|
||||
}
|
73
vendor/golang.org/x/crypto/curve25519/freeze_amd64.s
generated
vendored
73
vendor/golang.org/x/crypto/curve25519/freeze_amd64.s
generated
vendored
|
@ -1,73 +0,0 @@
|
|||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This code was translated into a form compatible with 6a from the public
|
||||
// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
|
||||
|
||||
// +build amd64,!gccgo,!appengine
|
||||
|
||||
#include "const_amd64.h"
|
||||
|
||||
// func freeze(inout *[5]uint64)
|
||||
TEXT ·freeze(SB),7,$0-8
|
||||
MOVQ inout+0(FP), DI
|
||||
|
||||
MOVQ 0(DI),SI
|
||||
MOVQ 8(DI),DX
|
||||
MOVQ 16(DI),CX
|
||||
MOVQ 24(DI),R8
|
||||
MOVQ 32(DI),R9
|
||||
MOVQ $REDMASK51,AX
|
||||
MOVQ AX,R10
|
||||
SUBQ $18,R10
|
||||
MOVQ $3,R11
|
||||
REDUCELOOP:
|
||||
MOVQ SI,R12
|
||||
SHRQ $51,R12
|
||||
ANDQ AX,SI
|
||||
ADDQ R12,DX
|
||||
MOVQ DX,R12
|
||||
SHRQ $51,R12
|
||||
ANDQ AX,DX
|
||||
ADDQ R12,CX
|
||||
MOVQ CX,R12
|
||||
SHRQ $51,R12
|
||||
ANDQ AX,CX
|
||||
ADDQ R12,R8
|
||||
MOVQ R8,R12
|
||||
SHRQ $51,R12
|
||||
ANDQ AX,R8
|
||||
ADDQ R12,R9
|
||||
MOVQ R9,R12
|
||||
SHRQ $51,R12
|
||||
ANDQ AX,R9
|
||||
IMUL3Q $19,R12,R12
|
||||
ADDQ R12,SI
|
||||
SUBQ $1,R11
|
||||
JA REDUCELOOP
|
||||
MOVQ $1,R12
|
||||
CMPQ R10,SI
|
||||
CMOVQLT R11,R12
|
||||
CMPQ AX,DX
|
||||
CMOVQNE R11,R12
|
||||
CMPQ AX,CX
|
||||
CMOVQNE R11,R12
|
||||
CMPQ AX,R8
|
||||
CMOVQNE R11,R12
|
||||
CMPQ AX,R9
|
||||
CMOVQNE R11,R12
|
||||
NEGQ R12
|
||||
ANDQ R12,AX
|
||||
ANDQ R12,R10
|
||||
SUBQ R10,SI
|
||||
SUBQ AX,DX
|
||||
SUBQ AX,CX
|
||||
SUBQ AX,R8
|
||||
SUBQ AX,R9
|
||||
MOVQ SI,0(DI)
|
||||
MOVQ DX,8(DI)
|
||||
MOVQ CX,16(DI)
|
||||
MOVQ R8,24(DI)
|
||||
MOVQ R9,32(DI)
|
||||
RET
|
1377
vendor/golang.org/x/crypto/curve25519/ladderstep_amd64.s
generated
vendored
1377
vendor/golang.org/x/crypto/curve25519/ladderstep_amd64.s
generated
vendored
File diff suppressed because it is too large
Load diff
240
vendor/golang.org/x/crypto/curve25519/mont25519_amd64.go
generated
vendored
240
vendor/golang.org/x/crypto/curve25519/mont25519_amd64.go
generated
vendored
|
@ -1,240 +0,0 @@
|
|||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build amd64,!gccgo,!appengine
|
||||
|
||||
package curve25519
|
||||
|
||||
// These functions are implemented in the .s files. The names of the functions
|
||||
// in the rest of the file are also taken from the SUPERCOP sources to help
|
||||
// people following along.
|
||||
|
||||
//go:noescape
|
||||
|
||||
func cswap(inout *[5]uint64, v uint64)
|
||||
|
||||
//go:noescape
|
||||
|
||||
func ladderstep(inout *[5][5]uint64)
|
||||
|
||||
//go:noescape
|
||||
|
||||
func freeze(inout *[5]uint64)
|
||||
|
||||
//go:noescape
|
||||
|
||||
func mul(dest, a, b *[5]uint64)
|
||||
|
||||
//go:noescape
|
||||
|
||||
func square(out, in *[5]uint64)
|
||||
|
||||
// mladder uses a Montgomery ladder to calculate (xr/zr) *= s.
|
||||
func mladder(xr, zr *[5]uint64, s *[32]byte) {
|
||||
var work [5][5]uint64
|
||||
|
||||
work[0] = *xr
|
||||
setint(&work[1], 1)
|
||||
setint(&work[2], 0)
|
||||
work[3] = *xr
|
||||
setint(&work[4], 1)
|
||||
|
||||
j := uint(6)
|
||||
var prevbit byte
|
||||
|
||||
for i := 31; i >= 0; i-- {
|
||||
for j < 8 {
|
||||
bit := ((*s)[i] >> j) & 1
|
||||
swap := bit ^ prevbit
|
||||
prevbit = bit
|
||||
cswap(&work[1], uint64(swap))
|
||||
ladderstep(&work)
|
||||
j--
|
||||
}
|
||||
j = 7
|
||||
}
|
||||
|
||||
*xr = work[1]
|
||||
*zr = work[2]
|
||||
}
|
||||
|
||||
func scalarMult(out, in, base *[32]byte) {
|
||||
var e [32]byte
|
||||
copy(e[:], (*in)[:])
|
||||
e[0] &= 248
|
||||
e[31] &= 127
|
||||
e[31] |= 64
|
||||
|
||||
var t, z [5]uint64
|
||||
unpack(&t, base)
|
||||
mladder(&t, &z, &e)
|
||||
invert(&z, &z)
|
||||
mul(&t, &t, &z)
|
||||
pack(out, &t)
|
||||
}
|
||||
|
||||
func setint(r *[5]uint64, v uint64) {
|
||||
r[0] = v
|
||||
r[1] = 0
|
||||
r[2] = 0
|
||||
r[3] = 0
|
||||
r[4] = 0
|
||||
}
|
||||
|
||||
// unpack sets r = x where r consists of 5, 51-bit limbs in little-endian
|
||||
// order.
|
||||
func unpack(r *[5]uint64, x *[32]byte) {
|
||||
r[0] = uint64(x[0]) |
|
||||
uint64(x[1])<<8 |
|
||||
uint64(x[2])<<16 |
|
||||
uint64(x[3])<<24 |
|
||||
uint64(x[4])<<32 |
|
||||
uint64(x[5])<<40 |
|
||||
uint64(x[6]&7)<<48
|
||||
|
||||
r[1] = uint64(x[6])>>3 |
|
||||
uint64(x[7])<<5 |
|
||||
uint64(x[8])<<13 |
|
||||
uint64(x[9])<<21 |
|
||||
uint64(x[10])<<29 |
|
||||
uint64(x[11])<<37 |
|
||||
uint64(x[12]&63)<<45
|
||||
|
||||
r[2] = uint64(x[12])>>6 |
|
||||
uint64(x[13])<<2 |
|
||||
uint64(x[14])<<10 |
|
||||
uint64(x[15])<<18 |
|
||||
uint64(x[16])<<26 |
|
||||
uint64(x[17])<<34 |
|
||||
uint64(x[18])<<42 |
|
||||
uint64(x[19]&1)<<50
|
||||
|
||||
r[3] = uint64(x[19])>>1 |
|
||||
uint64(x[20])<<7 |
|
||||
uint64(x[21])<<15 |
|
||||
uint64(x[22])<<23 |
|
||||
uint64(x[23])<<31 |
|
||||
uint64(x[24])<<39 |
|
||||
uint64(x[25]&15)<<47
|
||||
|
||||
r[4] = uint64(x[25])>>4 |
|
||||
uint64(x[26])<<4 |
|
||||
uint64(x[27])<<12 |
|
||||
uint64(x[28])<<20 |
|
||||
uint64(x[29])<<28 |
|
||||
uint64(x[30])<<36 |
|
||||
uint64(x[31]&127)<<44
|
||||
}
|
||||
|
||||
// pack sets out = x where out is the usual, little-endian form of the 5,
|
||||
// 51-bit limbs in x.
|
||||
func pack(out *[32]byte, x *[5]uint64) {
|
||||
t := *x
|
||||
freeze(&t)
|
||||
|
||||
out[0] = byte(t[0])
|
||||
out[1] = byte(t[0] >> 8)
|
||||
out[2] = byte(t[0] >> 16)
|
||||
out[3] = byte(t[0] >> 24)
|
||||
out[4] = byte(t[0] >> 32)
|
||||
out[5] = byte(t[0] >> 40)
|
||||
out[6] = byte(t[0] >> 48)
|
||||
|
||||
out[6] ^= byte(t[1]<<3) & 0xf8
|
||||
out[7] = byte(t[1] >> 5)
|
||||
out[8] = byte(t[1] >> 13)
|
||||
out[9] = byte(t[1] >> 21)
|
||||
out[10] = byte(t[1] >> 29)
|
||||
out[11] = byte(t[1] >> 37)
|
||||
out[12] = byte(t[1] >> 45)
|
||||
|
||||
out[12] ^= byte(t[2]<<6) & 0xc0
|
||||
out[13] = byte(t[2] >> 2)
|
||||
out[14] = byte(t[2] >> 10)
|
||||
out[15] = byte(t[2] >> 18)
|
||||
out[16] = byte(t[2] >> 26)
|
||||
out[17] = byte(t[2] >> 34)
|
||||
out[18] = byte(t[2] >> 42)
|
||||
out[19] = byte(t[2] >> 50)
|
||||
|
||||
out[19] ^= byte(t[3]<<1) & 0xfe
|
||||
out[20] = byte(t[3] >> 7)
|
||||
out[21] = byte(t[3] >> 15)
|
||||
out[22] = byte(t[3] >> 23)
|
||||
out[23] = byte(t[3] >> 31)
|
||||
out[24] = byte(t[3] >> 39)
|
||||
out[25] = byte(t[3] >> 47)
|
||||
|
||||
out[25] ^= byte(t[4]<<4) & 0xf0
|
||||
out[26] = byte(t[4] >> 4)
|
||||
out[27] = byte(t[4] >> 12)
|
||||
out[28] = byte(t[4] >> 20)
|
||||
out[29] = byte(t[4] >> 28)
|
||||
out[30] = byte(t[4] >> 36)
|
||||
out[31] = byte(t[4] >> 44)
|
||||
}
|
||||
|
||||
// invert calculates r = x^-1 mod p using Fermat's little theorem.
|
||||
func invert(r *[5]uint64, x *[5]uint64) {
|
||||
var z2, z9, z11, z2_5_0, z2_10_0, z2_20_0, z2_50_0, z2_100_0, t [5]uint64
|
||||
|
||||
square(&z2, x) /* 2 */
|
||||
square(&t, &z2) /* 4 */
|
||||
square(&t, &t) /* 8 */
|
||||
mul(&z9, &t, x) /* 9 */
|
||||
mul(&z11, &z9, &z2) /* 11 */
|
||||
square(&t, &z11) /* 22 */
|
||||
mul(&z2_5_0, &t, &z9) /* 2^5 - 2^0 = 31 */
|
||||
|
||||
square(&t, &z2_5_0) /* 2^6 - 2^1 */
|
||||
for i := 1; i < 5; i++ { /* 2^20 - 2^10 */
|
||||
square(&t, &t)
|
||||
}
|
||||
mul(&z2_10_0, &t, &z2_5_0) /* 2^10 - 2^0 */
|
||||
|
||||
square(&t, &z2_10_0) /* 2^11 - 2^1 */
|
||||
for i := 1; i < 10; i++ { /* 2^20 - 2^10 */
|
||||
square(&t, &t)
|
||||
}
|
||||
mul(&z2_20_0, &t, &z2_10_0) /* 2^20 - 2^0 */
|
||||
|
||||
square(&t, &z2_20_0) /* 2^21 - 2^1 */
|
||||
for i := 1; i < 20; i++ { /* 2^40 - 2^20 */
|
||||
square(&t, &t)
|
||||
}
|
||||
mul(&t, &t, &z2_20_0) /* 2^40 - 2^0 */
|
||||
|
||||
square(&t, &t) /* 2^41 - 2^1 */
|
||||
for i := 1; i < 10; i++ { /* 2^50 - 2^10 */
|
||||
square(&t, &t)
|
||||
}
|
||||
mul(&z2_50_0, &t, &z2_10_0) /* 2^50 - 2^0 */
|
||||
|
||||
square(&t, &z2_50_0) /* 2^51 - 2^1 */
|
||||
for i := 1; i < 50; i++ { /* 2^100 - 2^50 */
|
||||
square(&t, &t)
|
||||
}
|
||||
mul(&z2_100_0, &t, &z2_50_0) /* 2^100 - 2^0 */
|
||||
|
||||
square(&t, &z2_100_0) /* 2^101 - 2^1 */
|
||||
for i := 1; i < 100; i++ { /* 2^200 - 2^100 */
|
||||
square(&t, &t)
|
||||
}
|
||||
mul(&t, &t, &z2_100_0) /* 2^200 - 2^0 */
|
||||
|
||||
square(&t, &t) /* 2^201 - 2^1 */
|
||||
for i := 1; i < 50; i++ { /* 2^250 - 2^50 */
|
||||
square(&t, &t)
|
||||
}
|
||||
mul(&t, &t, &z2_50_0) /* 2^250 - 2^0 */
|
||||
|
||||
square(&t, &t) /* 2^251 - 2^1 */
|
||||
square(&t, &t) /* 2^252 - 2^2 */
|
||||
square(&t, &t) /* 2^253 - 2^3 */
|
||||
|
||||
square(&t, &t) /* 2^254 - 2^4 */
|
||||
|
||||
square(&t, &t) /* 2^255 - 2^5 */
|
||||
mul(r, &t, &z11) /* 2^255 - 21 */
|
||||
}
|
169
vendor/golang.org/x/crypto/curve25519/mul_amd64.s
generated
vendored
169
vendor/golang.org/x/crypto/curve25519/mul_amd64.s
generated
vendored
|
@ -1,169 +0,0 @@
|
|||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This code was translated into a form compatible with 6a from the public
|
||||
// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
|
||||
|
||||
// +build amd64,!gccgo,!appengine
|
||||
|
||||
#include "const_amd64.h"
|
||||
|
||||
// func mul(dest, a, b *[5]uint64)
|
||||
TEXT ·mul(SB),0,$16-24
|
||||
MOVQ dest+0(FP), DI
|
||||
MOVQ a+8(FP), SI
|
||||
MOVQ b+16(FP), DX
|
||||
|
||||
MOVQ DX,CX
|
||||
MOVQ 24(SI),DX
|
||||
IMUL3Q $19,DX,AX
|
||||
MOVQ AX,0(SP)
|
||||
MULQ 16(CX)
|
||||
MOVQ AX,R8
|
||||
MOVQ DX,R9
|
||||
MOVQ 32(SI),DX
|
||||
IMUL3Q $19,DX,AX
|
||||
MOVQ AX,8(SP)
|
||||
MULQ 8(CX)
|
||||
ADDQ AX,R8
|
||||
ADCQ DX,R9
|
||||
MOVQ 0(SI),AX
|
||||
MULQ 0(CX)
|
||||
ADDQ AX,R8
|
||||
ADCQ DX,R9
|
||||
MOVQ 0(SI),AX
|
||||
MULQ 8(CX)
|
||||
MOVQ AX,R10
|
||||
MOVQ DX,R11
|
||||
MOVQ 0(SI),AX
|
||||
MULQ 16(CX)
|
||||
MOVQ AX,R12
|
||||
MOVQ DX,R13
|
||||
MOVQ 0(SI),AX
|
||||
MULQ 24(CX)
|
||||
MOVQ AX,R14
|
||||
MOVQ DX,R15
|
||||
MOVQ 0(SI),AX
|
||||
MULQ 32(CX)
|
||||
MOVQ AX,BX
|
||||
MOVQ DX,BP
|
||||
MOVQ 8(SI),AX
|
||||
MULQ 0(CX)
|
||||
ADDQ AX,R10
|
||||
ADCQ DX,R11
|
||||
MOVQ 8(SI),AX
|
||||
MULQ 8(CX)
|
||||
ADDQ AX,R12
|
||||
ADCQ DX,R13
|
||||
MOVQ 8(SI),AX
|
||||
MULQ 16(CX)
|
||||
ADDQ AX,R14
|
||||
ADCQ DX,R15
|
||||
MOVQ 8(SI),AX
|
||||
MULQ 24(CX)
|
||||
ADDQ AX,BX
|
||||
ADCQ DX,BP
|
||||
MOVQ 8(SI),DX
|
||||
IMUL3Q $19,DX,AX
|
||||
MULQ 32(CX)
|
||||
ADDQ AX,R8
|
||||
ADCQ DX,R9
|
||||
MOVQ 16(SI),AX
|
||||
MULQ 0(CX)
|
||||
ADDQ AX,R12
|
||||
ADCQ DX,R13
|
||||
MOVQ 16(SI),AX
|
||||
MULQ 8(CX)
|
||||
ADDQ AX,R14
|
||||
ADCQ DX,R15
|
||||
MOVQ 16(SI),AX
|
||||
MULQ 16(CX)
|
||||
ADDQ AX,BX
|
||||
ADCQ DX,BP
|
||||
MOVQ 16(SI),DX
|
||||
IMUL3Q $19,DX,AX
|
||||
MULQ 24(CX)
|
||||
ADDQ AX,R8
|
||||
ADCQ DX,R9
|
||||
MOVQ 16(SI),DX
|
||||
IMUL3Q $19,DX,AX
|
||||
MULQ 32(CX)
|
||||
ADDQ AX,R10
|
||||
ADCQ DX,R11
|
||||
MOVQ 24(SI),AX
|
||||
MULQ 0(CX)
|
||||
ADDQ AX,R14
|
||||
ADCQ DX,R15
|
||||
MOVQ 24(SI),AX
|
||||
MULQ 8(CX)
|
||||
ADDQ AX,BX
|
||||
ADCQ DX,BP
|
||||
MOVQ 0(SP),AX
|
||||
MULQ 24(CX)
|
||||
ADDQ AX,R10
|
||||
ADCQ DX,R11
|
||||
MOVQ 0(SP),AX
|
||||
MULQ 32(CX)
|
||||
ADDQ AX,R12
|
||||
ADCQ DX,R13
|
||||
MOVQ 32(SI),AX
|
||||
MULQ 0(CX)
|
||||
ADDQ AX,BX
|
||||
ADCQ DX,BP
|
||||
MOVQ 8(SP),AX
|
||||
MULQ 16(CX)
|
||||
ADDQ AX,R10
|
||||
ADCQ DX,R11
|
||||
MOVQ 8(SP),AX
|
||||
MULQ 24(CX)
|
||||
ADDQ AX,R12
|
||||
ADCQ DX,R13
|
||||
MOVQ 8(SP),AX
|
||||
MULQ 32(CX)
|
||||
ADDQ AX,R14
|
||||
ADCQ DX,R15
|
||||
MOVQ $REDMASK51,SI
|
||||
SHLQ $13,R9:R8
|
||||
ANDQ SI,R8
|
||||
SHLQ $13,R11:R10
|
||||
ANDQ SI,R10
|
||||
ADDQ R9,R10
|
||||
SHLQ $13,R13:R12
|
||||
ANDQ SI,R12
|
||||
ADDQ R11,R12
|
||||
SHLQ $13,R15:R14
|
||||
ANDQ SI,R14
|
||||
ADDQ R13,R14
|
||||
SHLQ $13,BP:BX
|
||||
ANDQ SI,BX
|
||||
ADDQ R15,BX
|
||||
IMUL3Q $19,BP,DX
|
||||
ADDQ DX,R8
|
||||
MOVQ R8,DX
|
||||
SHRQ $51,DX
|
||||
ADDQ R10,DX
|
||||
MOVQ DX,CX
|
||||
SHRQ $51,DX
|
||||
ANDQ SI,R8
|
||||
ADDQ R12,DX
|
||||
MOVQ DX,R9
|
||||
SHRQ $51,DX
|
||||
ANDQ SI,CX
|
||||
ADDQ R14,DX
|
||||
MOVQ DX,AX
|
||||
SHRQ $51,DX
|
||||
ANDQ SI,R9
|
||||
ADDQ BX,DX
|
||||
MOVQ DX,R10
|
||||
SHRQ $51,DX
|
||||
ANDQ SI,AX
|
||||
IMUL3Q $19,DX,DX
|
||||
ADDQ DX,R8
|
||||
ANDQ SI,R10
|
||||
MOVQ R8,0(DI)
|
||||
MOVQ CX,8(DI)
|
||||
MOVQ R9,16(DI)
|
||||
MOVQ AX,24(DI)
|
||||
MOVQ R10,32(DI)
|
||||
RET
|
132
vendor/golang.org/x/crypto/curve25519/square_amd64.s
generated
vendored
132
vendor/golang.org/x/crypto/curve25519/square_amd64.s
generated
vendored
|
@ -1,132 +0,0 @@
|
|||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This code was translated into a form compatible with 6a from the public
|
||||
// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
|
||||
|
||||
// +build amd64,!gccgo,!appengine
|
||||
|
||||
#include "const_amd64.h"
|
||||
|
||||
// func square(out, in *[5]uint64)
|
||||
TEXT ·square(SB),7,$0-16
|
||||
MOVQ out+0(FP), DI
|
||||
MOVQ in+8(FP), SI
|
||||
|
||||
MOVQ 0(SI),AX
|
||||
MULQ 0(SI)
|
||||
MOVQ AX,CX
|
||||
MOVQ DX,R8
|
||||
MOVQ 0(SI),AX
|
||||
SHLQ $1,AX
|
||||
MULQ 8(SI)
|
||||
MOVQ AX,R9
|
||||
MOVQ DX,R10
|
||||
MOVQ 0(SI),AX
|
||||
SHLQ $1,AX
|
||||
MULQ 16(SI)
|
||||
MOVQ AX,R11
|
||||
MOVQ DX,R12
|
||||
MOVQ 0(SI),AX
|
||||
SHLQ $1,AX
|
||||
MULQ 24(SI)
|
||||
MOVQ AX,R13
|
||||
MOVQ DX,R14
|
||||
MOVQ 0(SI),AX
|
||||
SHLQ $1,AX
|
||||
MULQ 32(SI)
|
||||
MOVQ AX,R15
|
||||
MOVQ DX,BX
|
||||
MOVQ 8(SI),AX
|
||||
MULQ 8(SI)
|
||||
ADDQ AX,R11
|
||||
ADCQ DX,R12
|
||||
MOVQ 8(SI),AX
|
||||
SHLQ $1,AX
|
||||
MULQ 16(SI)
|
||||
ADDQ AX,R13
|
||||
ADCQ DX,R14
|
||||
MOVQ 8(SI),AX
|
||||
SHLQ $1,AX
|
||||
MULQ 24(SI)
|
||||
ADDQ AX,R15
|
||||
ADCQ DX,BX
|
||||
MOVQ 8(SI),DX
|
||||
IMUL3Q $38,DX,AX
|
||||
MULQ 32(SI)
|
||||
ADDQ AX,CX
|
||||
ADCQ DX,R8
|
||||
MOVQ 16(SI),AX
|
||||
MULQ 16(SI)
|
||||
ADDQ AX,R15
|
||||
ADCQ DX,BX
|
||||
MOVQ 16(SI),DX
|
||||
IMUL3Q $38,DX,AX
|
||||
MULQ 24(SI)
|
||||
ADDQ AX,CX
|
||||
ADCQ DX,R8
|
||||
MOVQ 16(SI),DX
|
||||
IMUL3Q $38,DX,AX
|
||||
MULQ 32(SI)
|
||||
ADDQ AX,R9
|
||||
ADCQ DX,R10
|
||||
MOVQ 24(SI),DX
|
||||
IMUL3Q $19,DX,AX
|
||||
MULQ 24(SI)
|
||||
ADDQ AX,R9
|
||||
ADCQ DX,R10
|
||||
MOVQ 24(SI),DX
|
||||
IMUL3Q $38,DX,AX
|
||||
MULQ 32(SI)
|
||||
ADDQ AX,R11
|
||||
ADCQ DX,R12
|
||||
MOVQ 32(SI),DX
|
||||
IMUL3Q $19,DX,AX
|
||||
MULQ 32(SI)
|
||||
ADDQ AX,R13
|
||||
ADCQ DX,R14
|
||||
MOVQ $REDMASK51,SI
|
||||
SHLQ $13,R8:CX
|
||||
ANDQ SI,CX
|
||||
SHLQ $13,R10:R9
|
||||
ANDQ SI,R9
|
||||
ADDQ R8,R9
|
||||
SHLQ $13,R12:R11
|
||||
ANDQ SI,R11
|
||||
ADDQ R10,R11
|
||||
SHLQ $13,R14:R13
|
||||
ANDQ SI,R13
|
||||
ADDQ R12,R13
|
||||
SHLQ $13,BX:R15
|
||||
ANDQ SI,R15
|
||||
ADDQ R14,R15
|
||||
IMUL3Q $19,BX,DX
|
||||
ADDQ DX,CX
|
||||
MOVQ CX,DX
|
||||
SHRQ $51,DX
|
||||
ADDQ R9,DX
|
||||
ANDQ SI,CX
|
||||
MOVQ DX,R8
|
||||
SHRQ $51,DX
|
||||
ADDQ R11,DX
|
||||
ANDQ SI,R8
|
||||
MOVQ DX,R9
|
||||
SHRQ $51,DX
|
||||
ADDQ R13,DX
|
||||
ANDQ SI,R9
|
||||
MOVQ DX,AX
|
||||
SHRQ $51,DX
|
||||
ADDQ R15,DX
|
||||
ANDQ SI,AX
|
||||
MOVQ DX,R10
|
||||
SHRQ $51,DX
|
||||
IMUL3Q $19,DX,DX
|
||||
ADDQ DX,CX
|
||||
ANDQ SI,R10
|
||||
MOVQ CX,0(DI)
|
||||
MOVQ R8,8(DI)
|
||||
MOVQ R9,16(DI)
|
||||
MOVQ AX,24(DI)
|
||||
MOVQ R10,32(DI)
|
||||
RET
|
197
vendor/golang.org/x/crypto/otr/libotr_test_helper.c
generated
vendored
197
vendor/golang.org/x/crypto/otr/libotr_test_helper.c
generated
vendored
|
@ -1,197 +0,0 @@
|
|||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This code can be compiled and used to test the otr package against libotr.
|
||||
// See otr_test.go.
|
||||
|
||||
// +build ignore
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <proto.h>
|
||||
#include <message.h>
|
||||
#include <privkey.h>
|
||||
|
||||
static int g_session_established = 0;
|
||||
|
||||
OtrlPolicy policy(void *opdata, ConnContext *context) {
|
||||
return OTRL_POLICY_ALWAYS;
|
||||
}
|
||||
|
||||
int is_logged_in(void *opdata, const char *accountname, const char *protocol,
|
||||
const char *recipient) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void inject_message(void *opdata, const char *accountname, const char *protocol,
|
||||
const char *recipient, const char *message) {
|
||||
printf("%s\n", message);
|
||||
fflush(stdout);
|
||||
fprintf(stderr, "libotr helper sent: %s\n", message);
|
||||
}
|
||||
|
||||
void update_context_list(void *opdata) {}
|
||||
|
||||
void new_fingerprint(void *opdata, OtrlUserState us, const char *accountname,
|
||||
const char *protocol, const char *username,
|
||||
unsigned char fingerprint[20]) {
|
||||
fprintf(stderr, "NEW FINGERPRINT\n");
|
||||
g_session_established = 1;
|
||||
}
|
||||
|
||||
void write_fingerprints(void *opdata) {}
|
||||
|
||||
void gone_secure(void *opdata, ConnContext *context) {}
|
||||
|
||||
void gone_insecure(void *opdata, ConnContext *context) {}
|
||||
|
||||
void still_secure(void *opdata, ConnContext *context, int is_reply) {}
|
||||
|
||||
int max_message_size(void *opdata, ConnContext *context) { return 99999; }
|
||||
|
||||
const char *account_name(void *opdata, const char *account,
|
||||
const char *protocol) {
|
||||
return "ACCOUNT";
|
||||
}
|
||||
|
||||
void account_name_free(void *opdata, const char *account_name) {}
|
||||
|
||||
const char *error_message(void *opdata, ConnContext *context,
|
||||
OtrlErrorCode err_code) {
|
||||
return "ERR";
|
||||
}
|
||||
|
||||
void error_message_free(void *opdata, const char *msg) {}
|
||||
|
||||
void resent_msg_prefix_free(void *opdata, const char *prefix) {}
|
||||
|
||||
void handle_smp_event(void *opdata, OtrlSMPEvent smp_event,
|
||||
ConnContext *context, unsigned short progress_event,
|
||||
char *question) {}
|
||||
|
||||
void handle_msg_event(void *opdata, OtrlMessageEvent msg_event,
|
||||
ConnContext *context, const char *message,
|
||||
gcry_error_t err) {
|
||||
fprintf(stderr, "msg event: %d %s\n", msg_event, message);
|
||||
}
|
||||
|
||||
OtrlMessageAppOps uiops = {
|
||||
policy,
|
||||
NULL,
|
||||
is_logged_in,
|
||||
inject_message,
|
||||
update_context_list,
|
||||
new_fingerprint,
|
||||
write_fingerprints,
|
||||
gone_secure,
|
||||
gone_insecure,
|
||||
still_secure,
|
||||
max_message_size,
|
||||
account_name,
|
||||
account_name_free,
|
||||
NULL, /* received_symkey */
|
||||
error_message,
|
||||
error_message_free,
|
||||
NULL, /* resent_msg_prefix */
|
||||
resent_msg_prefix_free,
|
||||
handle_smp_event,
|
||||
handle_msg_event,
|
||||
NULL /* create_instag */,
|
||||
NULL /* convert_msg */,
|
||||
NULL /* convert_free */,
|
||||
NULL /* timer_control */,
|
||||
};
|
||||
|
||||
static const char kPrivateKeyData[] =
|
||||
"(privkeys (account (name \"account\") (protocol proto) (private-key (dsa "
|
||||
"(p "
|
||||
"#00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F"
|
||||
"30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E"
|
||||
"5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB"
|
||||
"8C031D3561FECEE72EBB4A090D450A9B7A857#) (q "
|
||||
"#00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#) (g "
|
||||
"#535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F"
|
||||
"1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F"
|
||||
"6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57"
|
||||
"597766A2F9CE3857D7ACE3E1E3BC1FC6F26#) (y "
|
||||
"#0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF"
|
||||
"2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93"
|
||||
"454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A"
|
||||
"3C0FF501E3DC673B76D7BABF349009B6ECF#) (x "
|
||||
"#14D0345A3562C480A039E3C72764F72D79043216#)))))\n";
|
||||
|
||||
int main() {
|
||||
OTRL_INIT;
|
||||
|
||||
// We have to write the private key information to a file because the libotr
|
||||
// API demands a filename to read from.
|
||||
const char *tmpdir = "/tmp";
|
||||
if (getenv("TMP")) {
|
||||
tmpdir = getenv("TMP");
|
||||
}
|
||||
|
||||
char private_key_file[256];
|
||||
snprintf(private_key_file, sizeof(private_key_file),
|
||||
"%s/libotr_test_helper_privatekeys-XXXXXX", tmpdir);
|
||||
int fd = mkstemp(private_key_file);
|
||||
if (fd == -1) {
|
||||
perror("creating temp file");
|
||||
}
|
||||
write(fd, kPrivateKeyData, sizeof(kPrivateKeyData) - 1);
|
||||
close(fd);
|
||||
|
||||
OtrlUserState userstate = otrl_userstate_create();
|
||||
otrl_privkey_read(userstate, private_key_file);
|
||||
unlink(private_key_file);
|
||||
|
||||
fprintf(stderr, "libotr helper started\n");
|
||||
|
||||
char buf[4096];
|
||||
|
||||
for (;;) {
|
||||
char *message = fgets(buf, sizeof(buf), stdin);
|
||||
if (strlen(message) == 0) {
|
||||
break;
|
||||
}
|
||||
message[strlen(message) - 1] = 0;
|
||||
fprintf(stderr, "libotr helper got: %s\n", message);
|
||||
|
||||
char *newmessage = NULL;
|
||||
OtrlTLV *tlvs;
|
||||
int ignore_message = otrl_message_receiving(
|
||||
userstate, &uiops, NULL, "account", "proto", "peer", message,
|
||||
&newmessage, &tlvs, NULL, NULL, NULL);
|
||||
if (tlvs) {
|
||||
otrl_tlv_free(tlvs);
|
||||
}
|
||||
|
||||
if (newmessage != NULL) {
|
||||
fprintf(stderr, "libotr got: %s\n", newmessage);
|
||||
otrl_message_free(newmessage);
|
||||
|
||||
gcry_error_t err;
|
||||
char *newmessage = NULL;
|
||||
|
||||
err = otrl_message_sending(userstate, &uiops, NULL, "account", "proto",
|
||||
"peer", 0, "test message", NULL, &newmessage,
|
||||
OTRL_FRAGMENT_SEND_SKIP, NULL, NULL, NULL);
|
||||
if (newmessage == NULL) {
|
||||
fprintf(stderr, "libotr didn't encrypt message\n");
|
||||
return 1;
|
||||
}
|
||||
write(1, newmessage, strlen(newmessage));
|
||||
write(1, "\n", 1);
|
||||
fprintf(stderr, "libotr sent: %s\n", newmessage);
|
||||
otrl_message_free(newmessage);
|
||||
|
||||
g_session_established = 0;
|
||||
write(1, "?OTRv2?\n", 8);
|
||||
fprintf(stderr, "libotr sent: ?OTRv2\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
1415
vendor/golang.org/x/crypto/otr/otr.go
generated
vendored
1415
vendor/golang.org/x/crypto/otr/otr.go
generated
vendored
File diff suppressed because it is too large
Load diff
572
vendor/golang.org/x/crypto/otr/smp.go
generated
vendored
572
vendor/golang.org/x/crypto/otr/smp.go
generated
vendored
|
@ -1,572 +0,0 @@
|
|||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This file implements the Socialist Millionaires Protocol as described in
|
||||
// http://www.cypherpunks.ca/otr/Protocol-v2-3.1.0.html. The protocol
|
||||
// specification is required in order to understand this code and, where
|
||||
// possible, the variable names in the code match up with the spec.
|
||||
|
||||
package otr
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"hash"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
type smpFailure string
|
||||
|
||||
func (s smpFailure) Error() string {
|
||||
return string(s)
|
||||
}
|
||||
|
||||
var smpFailureError = smpFailure("otr: SMP protocol failed")
|
||||
var smpSecretMissingError = smpFailure("otr: mutual secret needed")
|
||||
|
||||
const smpVersion = 1
|
||||
|
||||
const (
|
||||
smpState1 = iota
|
||||
smpState2
|
||||
smpState3
|
||||
smpState4
|
||||
)
|
||||
|
||||
type smpState struct {
|
||||
state int
|
||||
a2, a3, b2, b3, pb, qb *big.Int
|
||||
g2a, g3a *big.Int
|
||||
g2, g3 *big.Int
|
||||
g3b, papb, qaqb, ra *big.Int
|
||||
saved *tlv
|
||||
secret *big.Int
|
||||
question string
|
||||
}
|
||||
|
||||
func (c *Conversation) startSMP(question string) (tlvs []tlv) {
|
||||
if c.smp.state != smpState1 {
|
||||
tlvs = append(tlvs, c.generateSMPAbort())
|
||||
}
|
||||
tlvs = append(tlvs, c.generateSMP1(question))
|
||||
c.smp.question = ""
|
||||
c.smp.state = smpState2
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Conversation) resetSMP() {
|
||||
c.smp.state = smpState1
|
||||
c.smp.secret = nil
|
||||
c.smp.question = ""
|
||||
}
|
||||
|
||||
func (c *Conversation) processSMP(in tlv) (out tlv, complete bool, err error) {
|
||||
data := in.data
|
||||
|
||||
switch in.typ {
|
||||
case tlvTypeSMPAbort:
|
||||
if c.smp.state != smpState1 {
|
||||
err = smpFailureError
|
||||
}
|
||||
c.resetSMP()
|
||||
return
|
||||
case tlvTypeSMP1WithQuestion:
|
||||
// We preprocess this into a SMP1 message.
|
||||
nulPos := bytes.IndexByte(data, 0)
|
||||
if nulPos == -1 {
|
||||
err = errors.New("otr: SMP message with question didn't contain a NUL byte")
|
||||
return
|
||||
}
|
||||
c.smp.question = string(data[:nulPos])
|
||||
data = data[nulPos+1:]
|
||||
}
|
||||
|
||||
numMPIs, data, ok := getU32(data)
|
||||
if !ok || numMPIs > 20 {
|
||||
err = errors.New("otr: corrupt SMP message")
|
||||
return
|
||||
}
|
||||
|
||||
mpis := make([]*big.Int, numMPIs)
|
||||
for i := range mpis {
|
||||
var ok bool
|
||||
mpis[i], data, ok = getMPI(data)
|
||||
if !ok {
|
||||
err = errors.New("otr: corrupt SMP message")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
switch in.typ {
|
||||
case tlvTypeSMP1, tlvTypeSMP1WithQuestion:
|
||||
if c.smp.state != smpState1 {
|
||||
c.resetSMP()
|
||||
out = c.generateSMPAbort()
|
||||
return
|
||||
}
|
||||
if c.smp.secret == nil {
|
||||
err = smpSecretMissingError
|
||||
return
|
||||
}
|
||||
if err = c.processSMP1(mpis); err != nil {
|
||||
return
|
||||
}
|
||||
c.smp.state = smpState3
|
||||
out = c.generateSMP2()
|
||||
case tlvTypeSMP2:
|
||||
if c.smp.state != smpState2 {
|
||||
c.resetSMP()
|
||||
out = c.generateSMPAbort()
|
||||
return
|
||||
}
|
||||
if out, err = c.processSMP2(mpis); err != nil {
|
||||
out = c.generateSMPAbort()
|
||||
return
|
||||
}
|
||||
c.smp.state = smpState4
|
||||
case tlvTypeSMP3:
|
||||
if c.smp.state != smpState3 {
|
||||
c.resetSMP()
|
||||
out = c.generateSMPAbort()
|
||||
return
|
||||
}
|
||||
if out, err = c.processSMP3(mpis); err != nil {
|
||||
return
|
||||
}
|
||||
c.smp.state = smpState1
|
||||
c.smp.secret = nil
|
||||
complete = true
|
||||
case tlvTypeSMP4:
|
||||
if c.smp.state != smpState4 {
|
||||
c.resetSMP()
|
||||
out = c.generateSMPAbort()
|
||||
return
|
||||
}
|
||||
if err = c.processSMP4(mpis); err != nil {
|
||||
out = c.generateSMPAbort()
|
||||
return
|
||||
}
|
||||
c.smp.state = smpState1
|
||||
c.smp.secret = nil
|
||||
complete = true
|
||||
default:
|
||||
panic("unknown SMP message")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Conversation) calcSMPSecret(mutualSecret []byte, weStarted bool) {
|
||||
h := sha256.New()
|
||||
h.Write([]byte{smpVersion})
|
||||
if weStarted {
|
||||
h.Write(c.PrivateKey.PublicKey.Fingerprint())
|
||||
h.Write(c.TheirPublicKey.Fingerprint())
|
||||
} else {
|
||||
h.Write(c.TheirPublicKey.Fingerprint())
|
||||
h.Write(c.PrivateKey.PublicKey.Fingerprint())
|
||||
}
|
||||
h.Write(c.SSID[:])
|
||||
h.Write(mutualSecret)
|
||||
c.smp.secret = new(big.Int).SetBytes(h.Sum(nil))
|
||||
}
|
||||
|
||||
func (c *Conversation) generateSMP1(question string) tlv {
|
||||
var randBuf [16]byte
|
||||
c.smp.a2 = c.randMPI(randBuf[:])
|
||||
c.smp.a3 = c.randMPI(randBuf[:])
|
||||
g2a := new(big.Int).Exp(g, c.smp.a2, p)
|
||||
g3a := new(big.Int).Exp(g, c.smp.a3, p)
|
||||
h := sha256.New()
|
||||
|
||||
r2 := c.randMPI(randBuf[:])
|
||||
r := new(big.Int).Exp(g, r2, p)
|
||||
c2 := new(big.Int).SetBytes(hashMPIs(h, 1, r))
|
||||
d2 := new(big.Int).Mul(c.smp.a2, c2)
|
||||
d2.Sub(r2, d2)
|
||||
d2.Mod(d2, q)
|
||||
if d2.Sign() < 0 {
|
||||
d2.Add(d2, q)
|
||||
}
|
||||
|
||||
r3 := c.randMPI(randBuf[:])
|
||||
r.Exp(g, r3, p)
|
||||
c3 := new(big.Int).SetBytes(hashMPIs(h, 2, r))
|
||||
d3 := new(big.Int).Mul(c.smp.a3, c3)
|
||||
d3.Sub(r3, d3)
|
||||
d3.Mod(d3, q)
|
||||
if d3.Sign() < 0 {
|
||||
d3.Add(d3, q)
|
||||
}
|
||||
|
||||
var ret tlv
|
||||
if len(question) > 0 {
|
||||
ret.typ = tlvTypeSMP1WithQuestion
|
||||
ret.data = append(ret.data, question...)
|
||||
ret.data = append(ret.data, 0)
|
||||
} else {
|
||||
ret.typ = tlvTypeSMP1
|
||||
}
|
||||
ret.data = appendU32(ret.data, 6)
|
||||
ret.data = appendMPIs(ret.data, g2a, c2, d2, g3a, c3, d3)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (c *Conversation) processSMP1(mpis []*big.Int) error {
|
||||
if len(mpis) != 6 {
|
||||
return errors.New("otr: incorrect number of arguments in SMP1 message")
|
||||
}
|
||||
g2a := mpis[0]
|
||||
c2 := mpis[1]
|
||||
d2 := mpis[2]
|
||||
g3a := mpis[3]
|
||||
c3 := mpis[4]
|
||||
d3 := mpis[5]
|
||||
h := sha256.New()
|
||||
|
||||
r := new(big.Int).Exp(g, d2, p)
|
||||
s := new(big.Int).Exp(g2a, c2, p)
|
||||
r.Mul(r, s)
|
||||
r.Mod(r, p)
|
||||
t := new(big.Int).SetBytes(hashMPIs(h, 1, r))
|
||||
if c2.Cmp(t) != 0 {
|
||||
return errors.New("otr: ZKP c2 incorrect in SMP1 message")
|
||||
}
|
||||
r.Exp(g, d3, p)
|
||||
s.Exp(g3a, c3, p)
|
||||
r.Mul(r, s)
|
||||
r.Mod(r, p)
|
||||
t.SetBytes(hashMPIs(h, 2, r))
|
||||
if c3.Cmp(t) != 0 {
|
||||
return errors.New("otr: ZKP c3 incorrect in SMP1 message")
|
||||
}
|
||||
|
||||
c.smp.g2a = g2a
|
||||
c.smp.g3a = g3a
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Conversation) generateSMP2() tlv {
|
||||
var randBuf [16]byte
|
||||
b2 := c.randMPI(randBuf[:])
|
||||
c.smp.b3 = c.randMPI(randBuf[:])
|
||||
r2 := c.randMPI(randBuf[:])
|
||||
r3 := c.randMPI(randBuf[:])
|
||||
r4 := c.randMPI(randBuf[:])
|
||||
r5 := c.randMPI(randBuf[:])
|
||||
r6 := c.randMPI(randBuf[:])
|
||||
|
||||
g2b := new(big.Int).Exp(g, b2, p)
|
||||
g3b := new(big.Int).Exp(g, c.smp.b3, p)
|
||||
|
||||
r := new(big.Int).Exp(g, r2, p)
|
||||
h := sha256.New()
|
||||
c2 := new(big.Int).SetBytes(hashMPIs(h, 3, r))
|
||||
d2 := new(big.Int).Mul(b2, c2)
|
||||
d2.Sub(r2, d2)
|
||||
d2.Mod(d2, q)
|
||||
if d2.Sign() < 0 {
|
||||
d2.Add(d2, q)
|
||||
}
|
||||
|
||||
r.Exp(g, r3, p)
|
||||
c3 := new(big.Int).SetBytes(hashMPIs(h, 4, r))
|
||||
d3 := new(big.Int).Mul(c.smp.b3, c3)
|
||||
d3.Sub(r3, d3)
|
||||
d3.Mod(d3, q)
|
||||
if d3.Sign() < 0 {
|
||||
d3.Add(d3, q)
|
||||
}
|
||||
|
||||
c.smp.g2 = new(big.Int).Exp(c.smp.g2a, b2, p)
|
||||
c.smp.g3 = new(big.Int).Exp(c.smp.g3a, c.smp.b3, p)
|
||||
c.smp.pb = new(big.Int).Exp(c.smp.g3, r4, p)
|
||||
c.smp.qb = new(big.Int).Exp(g, r4, p)
|
||||
r.Exp(c.smp.g2, c.smp.secret, p)
|
||||
c.smp.qb.Mul(c.smp.qb, r)
|
||||
c.smp.qb.Mod(c.smp.qb, p)
|
||||
|
||||
s := new(big.Int)
|
||||
s.Exp(c.smp.g2, r6, p)
|
||||
r.Exp(g, r5, p)
|
||||
s.Mul(r, s)
|
||||
s.Mod(s, p)
|
||||
r.Exp(c.smp.g3, r5, p)
|
||||
cp := new(big.Int).SetBytes(hashMPIs(h, 5, r, s))
|
||||
|
||||
// D5 = r5 - r4 cP mod q and D6 = r6 - y cP mod q
|
||||
|
||||
s.Mul(r4, cp)
|
||||
r.Sub(r5, s)
|
||||
d5 := new(big.Int).Mod(r, q)
|
||||
if d5.Sign() < 0 {
|
||||
d5.Add(d5, q)
|
||||
}
|
||||
|
||||
s.Mul(c.smp.secret, cp)
|
||||
r.Sub(r6, s)
|
||||
d6 := new(big.Int).Mod(r, q)
|
||||
if d6.Sign() < 0 {
|
||||
d6.Add(d6, q)
|
||||
}
|
||||
|
||||
var ret tlv
|
||||
ret.typ = tlvTypeSMP2
|
||||
ret.data = appendU32(ret.data, 11)
|
||||
ret.data = appendMPIs(ret.data, g2b, c2, d2, g3b, c3, d3, c.smp.pb, c.smp.qb, cp, d5, d6)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (c *Conversation) processSMP2(mpis []*big.Int) (out tlv, err error) {
|
||||
if len(mpis) != 11 {
|
||||
err = errors.New("otr: incorrect number of arguments in SMP2 message")
|
||||
return
|
||||
}
|
||||
g2b := mpis[0]
|
||||
c2 := mpis[1]
|
||||
d2 := mpis[2]
|
||||
g3b := mpis[3]
|
||||
c3 := mpis[4]
|
||||
d3 := mpis[5]
|
||||
pb := mpis[6]
|
||||
qb := mpis[7]
|
||||
cp := mpis[8]
|
||||
d5 := mpis[9]
|
||||
d6 := mpis[10]
|
||||
h := sha256.New()
|
||||
|
||||
r := new(big.Int).Exp(g, d2, p)
|
||||
s := new(big.Int).Exp(g2b, c2, p)
|
||||
r.Mul(r, s)
|
||||
r.Mod(r, p)
|
||||
s.SetBytes(hashMPIs(h, 3, r))
|
||||
if c2.Cmp(s) != 0 {
|
||||
err = errors.New("otr: ZKP c2 failed in SMP2 message")
|
||||
return
|
||||
}
|
||||
|
||||
r.Exp(g, d3, p)
|
||||
s.Exp(g3b, c3, p)
|
||||
r.Mul(r, s)
|
||||
r.Mod(r, p)
|
||||
s.SetBytes(hashMPIs(h, 4, r))
|
||||
if c3.Cmp(s) != 0 {
|
||||
err = errors.New("otr: ZKP c3 failed in SMP2 message")
|
||||
return
|
||||
}
|
||||
|
||||
c.smp.g2 = new(big.Int).Exp(g2b, c.smp.a2, p)
|
||||
c.smp.g3 = new(big.Int).Exp(g3b, c.smp.a3, p)
|
||||
|
||||
r.Exp(g, d5, p)
|
||||
s.Exp(c.smp.g2, d6, p)
|
||||
r.Mul(r, s)
|
||||
s.Exp(qb, cp, p)
|
||||
r.Mul(r, s)
|
||||
r.Mod(r, p)
|
||||
|
||||
s.Exp(c.smp.g3, d5, p)
|
||||
t := new(big.Int).Exp(pb, cp, p)
|
||||
s.Mul(s, t)
|
||||
s.Mod(s, p)
|
||||
t.SetBytes(hashMPIs(h, 5, s, r))
|
||||
if cp.Cmp(t) != 0 {
|
||||
err = errors.New("otr: ZKP cP failed in SMP2 message")
|
||||
return
|
||||
}
|
||||
|
||||
var randBuf [16]byte
|
||||
r4 := c.randMPI(randBuf[:])
|
||||
r5 := c.randMPI(randBuf[:])
|
||||
r6 := c.randMPI(randBuf[:])
|
||||
r7 := c.randMPI(randBuf[:])
|
||||
|
||||
pa := new(big.Int).Exp(c.smp.g3, r4, p)
|
||||
r.Exp(c.smp.g2, c.smp.secret, p)
|
||||
qa := new(big.Int).Exp(g, r4, p)
|
||||
qa.Mul(qa, r)
|
||||
qa.Mod(qa, p)
|
||||
|
||||
r.Exp(g, r5, p)
|
||||
s.Exp(c.smp.g2, r6, p)
|
||||
r.Mul(r, s)
|
||||
r.Mod(r, p)
|
||||
|
||||
s.Exp(c.smp.g3, r5, p)
|
||||
cp.SetBytes(hashMPIs(h, 6, s, r))
|
||||
|
||||
r.Mul(r4, cp)
|
||||
d5 = new(big.Int).Sub(r5, r)
|
||||
d5.Mod(d5, q)
|
||||
if d5.Sign() < 0 {
|
||||
d5.Add(d5, q)
|
||||
}
|
||||
|
||||
r.Mul(c.smp.secret, cp)
|
||||
d6 = new(big.Int).Sub(r6, r)
|
||||
d6.Mod(d6, q)
|
||||
if d6.Sign() < 0 {
|
||||
d6.Add(d6, q)
|
||||
}
|
||||
|
||||
r.ModInverse(qb, p)
|
||||
qaqb := new(big.Int).Mul(qa, r)
|
||||
qaqb.Mod(qaqb, p)
|
||||
|
||||
ra := new(big.Int).Exp(qaqb, c.smp.a3, p)
|
||||
r.Exp(qaqb, r7, p)
|
||||
s.Exp(g, r7, p)
|
||||
cr := new(big.Int).SetBytes(hashMPIs(h, 7, s, r))
|
||||
|
||||
r.Mul(c.smp.a3, cr)
|
||||
d7 := new(big.Int).Sub(r7, r)
|
||||
d7.Mod(d7, q)
|
||||
if d7.Sign() < 0 {
|
||||
d7.Add(d7, q)
|
||||
}
|
||||
|
||||
c.smp.g3b = g3b
|
||||
c.smp.qaqb = qaqb
|
||||
|
||||
r.ModInverse(pb, p)
|
||||
c.smp.papb = new(big.Int).Mul(pa, r)
|
||||
c.smp.papb.Mod(c.smp.papb, p)
|
||||
c.smp.ra = ra
|
||||
|
||||
out.typ = tlvTypeSMP3
|
||||
out.data = appendU32(out.data, 8)
|
||||
out.data = appendMPIs(out.data, pa, qa, cp, d5, d6, ra, cr, d7)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Conversation) processSMP3(mpis []*big.Int) (out tlv, err error) {
|
||||
if len(mpis) != 8 {
|
||||
err = errors.New("otr: incorrect number of arguments in SMP3 message")
|
||||
return
|
||||
}
|
||||
pa := mpis[0]
|
||||
qa := mpis[1]
|
||||
cp := mpis[2]
|
||||
d5 := mpis[3]
|
||||
d6 := mpis[4]
|
||||
ra := mpis[5]
|
||||
cr := mpis[6]
|
||||
d7 := mpis[7]
|
||||
h := sha256.New()
|
||||
|
||||
r := new(big.Int).Exp(g, d5, p)
|
||||
s := new(big.Int).Exp(c.smp.g2, d6, p)
|
||||
r.Mul(r, s)
|
||||
s.Exp(qa, cp, p)
|
||||
r.Mul(r, s)
|
||||
r.Mod(r, p)
|
||||
|
||||
s.Exp(c.smp.g3, d5, p)
|
||||
t := new(big.Int).Exp(pa, cp, p)
|
||||
s.Mul(s, t)
|
||||
s.Mod(s, p)
|
||||
t.SetBytes(hashMPIs(h, 6, s, r))
|
||||
if t.Cmp(cp) != 0 {
|
||||
err = errors.New("otr: ZKP cP failed in SMP3 message")
|
||||
return
|
||||
}
|
||||
|
||||
r.ModInverse(c.smp.qb, p)
|
||||
qaqb := new(big.Int).Mul(qa, r)
|
||||
qaqb.Mod(qaqb, p)
|
||||
|
||||
r.Exp(qaqb, d7, p)
|
||||
s.Exp(ra, cr, p)
|
||||
r.Mul(r, s)
|
||||
r.Mod(r, p)
|
||||
|
||||
s.Exp(g, d7, p)
|
||||
t.Exp(c.smp.g3a, cr, p)
|
||||
s.Mul(s, t)
|
||||
s.Mod(s, p)
|
||||
t.SetBytes(hashMPIs(h, 7, s, r))
|
||||
if t.Cmp(cr) != 0 {
|
||||
err = errors.New("otr: ZKP cR failed in SMP3 message")
|
||||
return
|
||||
}
|
||||
|
||||
var randBuf [16]byte
|
||||
r7 := c.randMPI(randBuf[:])
|
||||
rb := new(big.Int).Exp(qaqb, c.smp.b3, p)
|
||||
|
||||
r.Exp(qaqb, r7, p)
|
||||
s.Exp(g, r7, p)
|
||||
cr = new(big.Int).SetBytes(hashMPIs(h, 8, s, r))
|
||||
|
||||
r.Mul(c.smp.b3, cr)
|
||||
d7 = new(big.Int).Sub(r7, r)
|
||||
d7.Mod(d7, q)
|
||||
if d7.Sign() < 0 {
|
||||
d7.Add(d7, q)
|
||||
}
|
||||
|
||||
out.typ = tlvTypeSMP4
|
||||
out.data = appendU32(out.data, 3)
|
||||
out.data = appendMPIs(out.data, rb, cr, d7)
|
||||
|
||||
r.ModInverse(c.smp.pb, p)
|
||||
r.Mul(pa, r)
|
||||
r.Mod(r, p)
|
||||
s.Exp(ra, c.smp.b3, p)
|
||||
if r.Cmp(s) != 0 {
|
||||
err = smpFailureError
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Conversation) processSMP4(mpis []*big.Int) error {
|
||||
if len(mpis) != 3 {
|
||||
return errors.New("otr: incorrect number of arguments in SMP4 message")
|
||||
}
|
||||
rb := mpis[0]
|
||||
cr := mpis[1]
|
||||
d7 := mpis[2]
|
||||
h := sha256.New()
|
||||
|
||||
r := new(big.Int).Exp(c.smp.qaqb, d7, p)
|
||||
s := new(big.Int).Exp(rb, cr, p)
|
||||
r.Mul(r, s)
|
||||
r.Mod(r, p)
|
||||
|
||||
s.Exp(g, d7, p)
|
||||
t := new(big.Int).Exp(c.smp.g3b, cr, p)
|
||||
s.Mul(s, t)
|
||||
s.Mod(s, p)
|
||||
t.SetBytes(hashMPIs(h, 8, s, r))
|
||||
if t.Cmp(cr) != 0 {
|
||||
return errors.New("otr: ZKP cR failed in SMP4 message")
|
||||
}
|
||||
|
||||
r.Exp(rb, c.smp.a3, p)
|
||||
if r.Cmp(c.smp.papb) != 0 {
|
||||
return smpFailureError
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Conversation) generateSMPAbort() tlv {
|
||||
return tlv{typ: tlvTypeSMPAbort}
|
||||
}
|
||||
|
||||
func hashMPIs(h hash.Hash, magic byte, mpis ...*big.Int) []byte {
|
||||
if h != nil {
|
||||
h.Reset()
|
||||
} else {
|
||||
h = sha256.New()
|
||||
}
|
||||
|
||||
h.Write([]byte{magic})
|
||||
for _, mpi := range mpis {
|
||||
h.Write(appendMPI(nil, mpi))
|
||||
}
|
||||
return h.Sum(nil)
|
||||
}
|
7
vendor/golang.org/x/crypto/ssh/test/doc.go
generated
vendored
7
vendor/golang.org/x/crypto/ssh/test/doc.go
generated
vendored
|
@ -1,7 +0,0 @@
|
|||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package test contains integration tests for the
|
||||
// golang.org/x/crypto/ssh package.
|
||||
package test // import "golang.org/x/crypto/ssh/test"
|
173
vendor/golang.org/x/crypto/ssh/test/sshd_test_pw.c
generated
vendored
173
vendor/golang.org/x/crypto/ssh/test/sshd_test_pw.c
generated
vendored
|
@ -1,173 +0,0 @@
|
|||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// sshd_test_pw.c
|
||||
// Wrapper to inject test password data for sshd PAM authentication
|
||||
//
|
||||
// This wrapper implements custom versions of getpwnam, getpwnam_r,
|
||||
// getspnam and getspnam_r. These functions first call their real
|
||||
// libc versions, then check if the requested user matches test user
|
||||
// specified in env variable TEST_USER and if so replace the password
|
||||
// with crypted() value of TEST_PASSWD env variable.
|
||||
//
|
||||
// Compile:
|
||||
// gcc -Wall -shared -o sshd_test_pw.so -fPIC sshd_test_pw.c
|
||||
//
|
||||
// Compile with debug:
|
||||
// gcc -DVERBOSE -Wall -shared -o sshd_test_pw.so -fPIC sshd_test_pw.c
|
||||
//
|
||||
// Run sshd:
|
||||
// LD_PRELOAD="sshd_test_pw.so" TEST_USER="..." TEST_PASSWD="..." sshd ...
|
||||
|
||||
// +build ignore
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <string.h>
|
||||
#include <pwd.h>
|
||||
#include <shadow.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef VERBOSE
|
||||
#define DEBUG(X...) fprintf(stderr, X)
|
||||
#else
|
||||
#define DEBUG(X...) while (0) { }
|
||||
#endif
|
||||
|
||||
/* crypt() password */
|
||||
static char *
|
||||
pwhash(char *passwd) {
|
||||
return strdup(crypt(passwd, "$6$"));
|
||||
}
|
||||
|
||||
/* Pointers to real functions in libc */
|
||||
static struct passwd * (*real_getpwnam)(const char *) = NULL;
|
||||
static int (*real_getpwnam_r)(const char *, struct passwd *, char *, size_t, struct passwd **) = NULL;
|
||||
static struct spwd * (*real_getspnam)(const char *) = NULL;
|
||||
static int (*real_getspnam_r)(const char *, struct spwd *, char *, size_t, struct spwd **) = NULL;
|
||||
|
||||
/* Cached test user and test password */
|
||||
static char *test_user = NULL;
|
||||
static char *test_passwd_hash = NULL;
|
||||
|
||||
static void
|
||||
init(void) {
|
||||
/* Fetch real libc function pointers */
|
||||
real_getpwnam = dlsym(RTLD_NEXT, "getpwnam");
|
||||
real_getpwnam_r = dlsym(RTLD_NEXT, "getpwnam_r");
|
||||
real_getspnam = dlsym(RTLD_NEXT, "getspnam");
|
||||
real_getspnam_r = dlsym(RTLD_NEXT, "getspnam_r");
|
||||
|
||||
/* abort if env variables are not defined */
|
||||
if (getenv("TEST_USER") == NULL || getenv("TEST_PASSWD") == NULL) {
|
||||
fprintf(stderr, "env variables TEST_USER and TEST_PASSWD are missing\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Fetch test user and test password from env */
|
||||
test_user = strdup(getenv("TEST_USER"));
|
||||
test_passwd_hash = pwhash(getenv("TEST_PASSWD"));
|
||||
|
||||
DEBUG("sshd_test_pw init():\n");
|
||||
DEBUG("\treal_getpwnam: %p\n", real_getpwnam);
|
||||
DEBUG("\treal_getpwnam_r: %p\n", real_getpwnam_r);
|
||||
DEBUG("\treal_getspnam: %p\n", real_getspnam);
|
||||
DEBUG("\treal_getspnam_r: %p\n", real_getspnam_r);
|
||||
DEBUG("\tTEST_USER: '%s'\n", test_user);
|
||||
DEBUG("\tTEST_PASSWD: '%s'\n", getenv("TEST_PASSWD"));
|
||||
DEBUG("\tTEST_PASSWD_HASH: '%s'\n", test_passwd_hash);
|
||||
}
|
||||
|
||||
static int
|
||||
is_test_user(const char *name) {
|
||||
if (test_user != NULL && strcmp(test_user, name) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* getpwnam */
|
||||
|
||||
struct passwd *
|
||||
getpwnam(const char *name) {
|
||||
struct passwd *pw;
|
||||
|
||||
DEBUG("sshd_test_pw getpwnam(%s)\n", name);
|
||||
|
||||
if (real_getpwnam == NULL)
|
||||
init();
|
||||
if ((pw = real_getpwnam(name)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (is_test_user(name))
|
||||
pw->pw_passwd = strdup(test_passwd_hash);
|
||||
|
||||
return pw;
|
||||
}
|
||||
|
||||
/* getpwnam_r */
|
||||
|
||||
int
|
||||
getpwnam_r(const char *name,
|
||||
struct passwd *pwd,
|
||||
char *buf,
|
||||
size_t buflen,
|
||||
struct passwd **result) {
|
||||
int r;
|
||||
|
||||
DEBUG("sshd_test_pw getpwnam_r(%s)\n", name);
|
||||
|
||||
if (real_getpwnam_r == NULL)
|
||||
init();
|
||||
if ((r = real_getpwnam_r(name, pwd, buf, buflen, result)) != 0 || *result == NULL)
|
||||
return r;
|
||||
|
||||
if (is_test_user(name))
|
||||
pwd->pw_passwd = strdup(test_passwd_hash);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* getspnam */
|
||||
|
||||
struct spwd *
|
||||
getspnam(const char *name) {
|
||||
struct spwd *sp;
|
||||
|
||||
DEBUG("sshd_test_pw getspnam(%s)\n", name);
|
||||
|
||||
if (real_getspnam == NULL)
|
||||
init();
|
||||
if ((sp = real_getspnam(name)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (is_test_user(name))
|
||||
sp->sp_pwdp = strdup(test_passwd_hash);
|
||||
|
||||
return sp;
|
||||
}
|
||||
|
||||
/* getspnam_r */
|
||||
|
||||
int
|
||||
getspnam_r(const char *name,
|
||||
struct spwd *spbuf,
|
||||
char *buf,
|
||||
size_t buflen,
|
||||
struct spwd **spbufp) {
|
||||
int r;
|
||||
|
||||
DEBUG("sshd_test_pw getspnam_r(%s)\n", name);
|
||||
|
||||
if (real_getspnam_r == NULL)
|
||||
init();
|
||||
if ((r = real_getspnam_r(name, spbuf, buf, buflen, spbufp)) != 0)
|
||||
return r;
|
||||
|
||||
if (is_test_user(name))
|
||||
spbuf->sp_pwdp = strdup(test_passwd_hash);
|
||||
|
||||
return r;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue