package  ecdsa 
 
import  ( 
	"crypto/elliptic"  
	"crypto/internal/fips140only"  
	"errors"  
	"io"  
	"math/big"  
	"math/rand/v2"  
 
	"golang.org/x/crypto/cryptobyte"  
	"golang.org/x/crypto/cryptobyte/asn1"  
) 
 
 
 
 
func  generateLegacy(c  elliptic .Curve , rand  io .Reader ) (*PrivateKey , error ) { 
	if  fips140only .Enabled  { 
		return  nil , errors .New ("crypto/ecdsa: use of custom curves is not allowed in FIPS 140-only mode" ) 
	} 
 
	k , err  := randFieldElement (c , rand ) 
	if  err  != nil  { 
		return  nil , err  
	} 
 
	priv  := new (PrivateKey ) 
	priv .PublicKey .Curve  = c  
	priv .D  = k  
	priv .PublicKey .X , priv .PublicKey .Y  = c .ScalarBaseMult (k .Bytes ()) 
	return  priv , nil  
} 
 
 
 
 
func  hashToInt(hash  []byte , c  elliptic .Curve ) *big .Int  { 
	orderBits  := c .Params ().N .BitLen () 
	orderBytes  := (orderBits  + 7 ) / 8  
	if  len (hash ) > orderBytes  { 
		hash  = hash [:orderBytes ] 
	} 
 
	ret  := new (big .Int ).SetBytes (hash ) 
	excess  := len (hash )*8  - orderBits  
	if  excess  > 0  { 
		ret .Rsh (ret , uint (excess )) 
	} 
	return  ret  
} 
 
var  errZeroParam = errors .New ("zero parameter" ) 
 
 
 
 
 
 
func  Sign  (rand  io .Reader , priv  *PrivateKey , hash  []byte ) (r , s  *big .Int , err  error ) { 
	sig , err  := SignASN1 (rand , priv , hash ) 
	if  err  != nil  { 
		return  nil , nil , err  
	} 
 
	r , s  = new (big .Int ), new (big .Int ) 
	var  inner  cryptobyte .String  
	input  := cryptobyte .String (sig ) 
	if  !input .ReadASN1 (&inner , asn1 .SEQUENCE ) || 
		!input .Empty () || 
		!inner .ReadASN1Integer (r ) || 
		!inner .ReadASN1Integer (s ) || 
		!inner .Empty () { 
		return  nil , nil , errors .New ("invalid ASN.1 from SignASN1" ) 
	} 
	return  r , s , nil  
} 
 
func  signLegacy(priv  *PrivateKey , csprng  io .Reader , hash  []byte ) (sig  []byte , err  error ) { 
	if  fips140only .Enabled  { 
		return  nil , errors .New ("crypto/ecdsa: use of custom curves is not allowed in FIPS 140-only mode" ) 
	} 
 
	c  := priv .Curve  
 
	 
	var  seed  [32 ]byte  
	if  _ , err  := io .ReadFull (csprng , seed [:]); err  != nil  { 
		return  nil , err  
	} 
	for  i , b  := range  priv .D .Bytes () { 
		seed [i %32 ] ^= b  
	} 
	for  i , b  := range  hash  { 
		seed [i %32 ] ^= b  
	} 
	csprng  = rand .NewChaCha8 (seed ) 
 
	 
	N  := c .Params ().N  
	if  N .Sign () == 0  { 
		return  nil , errZeroParam  
	} 
	var  k , kInv , r , s  *big .Int  
	for  { 
		for  { 
			k , err  = randFieldElement (c , csprng ) 
			if  err  != nil  { 
				return  nil , err  
			} 
 
			kInv  = new (big .Int ).ModInverse (k , N ) 
 
			r , _ = c .ScalarBaseMult (k .Bytes ()) 
			r .Mod (r , 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 , N )  
		if  s .Sign () != 0  { 
			break  
		} 
	} 
 
	return  encodeSignature (r .Bytes (), s .Bytes ()) 
} 
 
 
 
 
 
 
 
func  Verify  (pub  *PublicKey , hash  []byte , r , s  *big .Int ) bool  { 
	if  r .Sign () <= 0  || s .Sign () <= 0  { 
		return  false  
	} 
	sig , err  := encodeSignature (r .Bytes (), s .Bytes ()) 
	if  err  != nil  { 
		return  false  
	} 
	return  VerifyASN1 (pub , hash , sig ) 
} 
 
func  verifyLegacy(pub  *PublicKey , hash  []byte , sig  []byte ) bool  { 
	if  fips140only .Enabled  { 
		panic ("crypto/ecdsa: use of custom curves is not allowed in FIPS 140-only mode" ) 
	} 
 
	rBytes , sBytes , err  := parseSignature (sig ) 
	if  err  != nil  { 
		return  false  
	} 
	r , s  := new (big .Int ).SetBytes (rBytes ), new (big .Int ).SetBytes (sBytes ) 
 
	c  := pub .Curve  
	N  := c .Params ().N  
 
	if  r .Sign () <= 0  || s .Sign () <= 0  { 
		return  false  
	} 
	if  r .Cmp (N ) >= 0  || s .Cmp (N ) >= 0  { 
		return  false  
	} 
 
	 
	e  := hashToInt (hash , c ) 
	w  := new (big .Int ).ModInverse (s , N ) 
 
	u1  := e .Mul (e , w ) 
	u1 .Mod (u1 , N ) 
	u2  := w .Mul (r , w ) 
	u2 .Mod (u2 , N ) 
 
	x1 , y1  := c .ScalarBaseMult (u1 .Bytes ()) 
	x2 , y2  := c .ScalarMult (pub .X , pub .Y , u2 .Bytes ()) 
	x , y  := c .Add (x1 , y1 , x2 , y2 ) 
 
	if  x .Sign () == 0  && y .Sign () == 0  { 
		return  false  
	} 
	x .Mod (x , N ) 
	return  x .Cmp (r ) == 0  
} 
 
var  one = new (big .Int ).SetInt64 (1 ) 
 
 
 
func  randFieldElement(c  elliptic .Curve , rand  io .Reader ) (k  *big .Int , err  error ) { 
	for  { 
		N  := c .Params ().N  
		b  := make ([]byte , (N .BitLen ()+7 )/8 ) 
		if  _, err  = io .ReadFull (rand , b ); err  != nil  { 
			return  
		} 
		if  excess  := len (b )*8  - N .BitLen (); excess  > 0  { 
			b [0 ] >>= excess  
		} 
		k  = new (big .Int ).SetBytes (b ) 
		if  k .Sign () != 0  && k .Cmp (N ) < 0  { 
			return  
		} 
	} 
} 
  
The pages are generated with Golds   v0.7.9-preview . (GOOS=linux GOARCH=amd64)
Golds  is a Go 101  project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101  (reachable from the left QR code) to get the latest news of Golds .