
    Djo9                        U d dl Z d dlmZ d dlmZmZ d dlmZmZm	Z	m
Z
mZmZ d dlmZmZ d dlmZ d dlmZ d dlmZmZ d	d
lmZ 	  ed           G d d                      Zd edd          iZeeef         ed<   dedefdZdededefdZ de
de
de
fdZ!e G d d                      Z"e G d d                       Z#e G d! d"                      Z$e G d# d$                      Z%dS )%    N)	dataclass)SequenceTuple)ECDHEllipticCurveEllipticCurvePrivateKeyEllipticCurvePublicKeyEllipticCurvePublicNumbersderive_private_key)HashHashAlgorithm)HMAC)HKDF)EncodingPublicFormat   )	bytes2intT)frozenc                   (    e Zd ZU dZeed<   eed<   dS )_CurveParamsz:Weierstrass curve parameters needed for EC point addition.primeaN)__name__
__module____qualname____doc__int__annotations__     E/home/thesage/.hermes/venv/lib/python3.11/site-packages/fido2/arkg.pyr   r   8   s(         DDJJJ
FFFFFr    r   	secp256r1l   ?               @ l   ?               @ )r   r   _CURVE_PARAMScurvereturnc                 r    	 t           | j                 S # t          $ r t          d| j                   w xY w)zELook up curve parameters, or raise ValueError for unsupported curves.zUnsupported curve: )r#   nameKeyError
ValueError)r$   s    r!   _params_for_curver*   H   sH    =UZ(( = = =;uz;;<<<=s    "6r   bc                 r     t           fdt          t                               D                       S )Nc              3   :   K   | ]}|         |         z  V  d S )Nr   ).0ir   r+   s     r!   	<genexpr>z_strxor.<locals>.<genexpr>Q   s/      441!444444r    )bytesrangelen)r   r+   s   ``r!   _strxorr4   P   s6    44444eCFFmm444444r    p1p2c                 >   | j         j        |j         j        k    rt          d          t          | j                   }|                                 }|                                }|j        |j        }}|j        |j        }}|j        }	||k    r/||k    r)d|z  |z  |j        z   t          d|z  d|	          z  |	z  }
n||z
  t          ||z
  d|	          z  |	z  }
|
|
z  |z
  |z
  |	z  }|
||z
  z  |z
  |	z  }t          ||| j                                                   S )zCAdd two EC points. Both points must be on the same supported curve.z'Cannot add points from different curves      )r$   r'   r)   r*   public_numbersxyr   r   powr
   
public_key)r5   r6   paramsn1n2x1y1x2y2plamx3y3s                r!   
_point_addrK   T   s*    
x}%%BCCCrx((F					B					BT24BT24BA	RxxB"HH2v{VX%QVR););;a?Bw#b2gr1---1
)b.2
	"B
b/B
!	#B%b"bh77BBDDDr    c                   l    e Zd ZU dZeed<   eed<   eed<   eed<   dedefdZded	ed
e	e         fdZ
dS )_HTFa/  
    hash_to_field(msg, count)

    Parameters:
    - DST, a domain separation tag (see Section 3.1).
    - F, a finite field of characteristic p and order q = p^m.
    - p, the characteristic of F (see immediately above).
    - m, the extension degree of F, m >= 1 (see immediately above).
    - L = ceil((ceil(log2(p)) + k) / 8), where k is the security
      parameter of the suite (e.g., k = 128).
    - expand_message, a function that expands a byte string and
      domain separation tag into a uniformly random byte string
      (see Section 5.3).
    DSTrG   Lr   msglen_in_bytesc                 V   | j         j        }| |z   }|dk    s|dk    st          | j                  dk    rt	          d          | j        t          j        dt          | j                            z   }| j         j        J d| j         j        z  }t          j        d|          }||z   |z   dz   |z   }t          | j                   }	|	                    |           |		                                }
|
}t                      }t          d|dz             D ]}}t          | j                   }	|	                    |t          j        d|          z   |z              |		                                }|                    |           t          |
|          }~t          |d|                   S )	a}  
        expand_message_xmd(msg, DST, len_in_bytes)

        Parameters:
        - H, a hash function (see requirements above).
        - b_in_bytes, b / 8 for b the output size of H in bits.
          For example, for b = 256, b_in_bytes = 32.
        - s_in_bytes, the input block size of H, measured in bytes (see
          discussion above). For example, for SHA-256, s_in_bytes = 64.

        Input:
        - msg, a byte string.
        - DST, a byte string of at most 255 bytes.
          See below for information on using longer DSTs.
        - len_in_bytes, the length of the requested output in bytes,
          not greater than the lesser of (255 * b_in_bytes) or 2^16-1.

        Output:
        - uniform_bytes, a byte string.

        Steps:
        1.  ell = ceil(len_in_bytes / b_in_bytes)
        2.  ABORT if ell > 255 or len_in_bytes > 65535 or len(DST) > 255
        3.  DST_prime = DST || I2OSP(len(DST), 1)
        4.  Z_pad = I2OSP(0, s_in_bytes)
        5.  l_i_b_str = I2OSP(len_in_bytes, 2)
        6.  msg_prime = Z_pad || msg || l_i_b_str || I2OSP(0, 1) || DST_prime
        7.  b_0 = H(msg_prime)
        8.  b_1 = H(b_0 || I2OSP(1, 1) || DST_prime)
        9.  for i in (2, ..., ell):
        10.    b_i = H(strxor(b_0, b_(i - 1)) || I2OSP(i, 1) || DST_prime)
        11. uniform_bytes = b_1 || ... || b_ell
        12. return substr(uniform_bytes, 0, len_in_bytes)
           i  zInvalid size of input/output>BN    z>Hr   )r   digest_sizer3   rN   r)   structpack
block_sizeupdatefinalize	bytearrayr2   extendr4   r1   )selfrP   rQ   
b_in_bytesell	dst_primez_pad	l_i_b_str	msg_primedb_0b_xoruniform_bytesr/   b_is                  r!   expand_message_xmdz_HTF.expand_message_xmd   s   F Y*
+,99u,,DH0C0C;<<<Hv{4TX???	y#///$)..Kl33	CK)+g5	A	OO	jjll!q#'"" 	& 	&ATYAHHUV[q111I=>>>**,,C  %%%C%%EE]=L=1222r    countr%   c                    |                      ||| j        z            }t                      }t          |          D ]J}| j        |z  }|||| j        z            }t	          |          | j        z  }|                    |           K|S )a  
        hash_to_field(msg, count)

        Input:
        - msg, a byte string containing the message to hash.
        - count, the number of elements of F to output.

        Output:
        - (u_0, ..., u_(count - 1)), a list of field elements.

        Steps:
        1. len_in_bytes = count * m * L
        2. uniform_bytes = expand_message(msg, DST, len_in_bytes)
        3. for i in (0, ..., count - 1):
        4.   for j in (0, ..., m - 1):
        5.     elm_offset = L * (j + i * m)
        6.     tv = substr(uniform_bytes, elm_offset, L)
        7.     e_j = OS2IP(tv) mod p
        8.   u_i = (e_0, ..., e_(m - 1))
        9. return (u_0, ..., u_(count - 1))
        )rj   rO   listr2   r   rG   append)	r^   rP   rk   rh   elementsr/   offsettve_js	            r!   hash_to_fieldz_HTF.hash_to_field   s    . //UTV^DD66u 	! 	!AVaZFv78BB--$&(COOC    r    N)r   r   r   r   r1   r   r   r   rj   r   rs   r   r    r!   rM   rM   m   s           
JJJ
FFF
FFF
:3e :33 :3 :3 :3 :3x s x}      r    rM   c                   V    e Zd ZU eed<   eed<   eed<   dededefdZde	d	ede	fd
Z
dS )_BLcrvr   DST_extikm_tauctxr%   c                     d| j         z   |z   }t          || j        j        d| j                  }|                    |d          d         }|S )a  
        BL-PRF(ikm_tau, ctx) -> tau

            DST_tau = 'ARKG-BL-EC.' || DST_ext || ctx
            tau = hash_to_field(tau, 1) with the parameters:
                DST: DST_tau
                F: GF(N), the scalar field
                   of the prime order subgroup of crv
                p: N
                m: 1
                L: The L defined in hash-to-crv-suite
                expand_message: The expand_message function
                                defined in hash-to-crv-suite
        s   ARKG-BL-EC.0   r   r   )rw   rM   rv   group_orderr   rs   )r^   rx   ry   dst_tauhtftaus         r!   prfz_BL.prf   sN     !4</#57DH0"di@@++A.
r    pkr   c                 p    t          || j                                                  }t          ||          S )z[
        BL-Blind-Public-Key(pk, tau) -> pk_tau

            pk_tau = pk + tau * G
        )r   rv   r?   rK   )r^   r   r   tau_gs       r!   blind_public_keyz_BL.blind_public_key   s1     #311<<>>"e$$$r    N)r   r   r   r   r   r   r1   r   r   r	   r   r   r    r!   ru   ru      s         	
NNN5 u     *	%(	%/2	%		% 	% 	% 	% 	% 	%r    ru   c            
           e Zd ZU eed<   eed<   eed<   dedefdZde	dedede
eef         fd	Zde	dedede
eef         fd
ZdS )_KEMrv   r   rw   ikmr%   c                     t          d| j        z   | j        j        d| j                  }|                    |d          d         }t          || j                  S )a  
        Sub-Kem-Derive-Key-Pair(ikm) -> (pk, sk)

            sk = hash_to_field(ikm, 1) with the parameters:
                DST: 'ARKG-KEM-ECDH-KG.' || DST_ext
                F: GF(N), the scalar field
                  of the prime order subgroup of crv
                p: N
                m: 1
                L: The L defined in hash-to-crv-suite
                expand_message: The expand_message function
                                defined in hash-to-crv-suite

            pk = sk * G
        s   ARKG-KEM-ECDH-KG.r{   r   r   )rM   rw   rv   r|   r   rs   r   )r^   r   r~   sks       r!   sub_kem_derive_key_pairz_KEM.sub_kem_derive_key_pair  s[       4</H I	
 
 sA&&q)!"dh///r    r   ry   c                     |                      |          }|                                }|                    t                      |          }|                    t
          j        t          j                  }||fS )a  
        ECDH(pk, sk) represents the compact output of ECDH [RFC6090]
        using public key (curve point) pk and private key (exponent) sk.

        G is the generator of the prime order subgroup of crv.

        N is the order of G.

        Sub-Kem-Encaps(pk, ikm, ctx) -> (k, c)

            (pk', sk') = Sub-Kem-Derive-Key-Pair(ikm)

            k = ECDH(pk, sk')
            c = Elliptic-Curve-Point-to-Octet-String(pk')
        )	r   r?   exchanger   public_bytesr   X962r   UncompressedPoint)r^   r   r   ry   sk_primepk_primekcs           r!   sub_kem_encapsz_KEM.sub_kem_encaps*  sd    $ //44&&((dffb))!!(-1OPP!tr    c                    d| j         z   |z   }|                     |||          \  }}t          | j        | j        j        dd| j         z   |z                                 |          }t          || j                  }|                    |           |                                dd         }	t          | j        t          |          dd| j         z   |z                                 |          }
|	|z   }|
|fS )a  
        KEM-Encaps(pk, ikm, ctx) -> (k, c)

            ctx_sub = 'ARKG-KEM-HMAC.' || DST_ext || ctx
            (k', c') = Sub-Kem-Encaps(pk, ikm, ctx_sub)

            prk = HKDF-Extract with the arguments:
                Hash: Hash
                salt: not set
                IKM: k'

            mk = HKDF-Expand with the arguments:
                Hash: Hash
                PRK: prk
                info: 'ARKG-KEM-HMAC-mac.' || DST_ext || ctx
                L: L
            t = HMAC-Hash-128(K=mk, text=c')

            k = HKDF-Expand with the arguments:
                Hash: Hash
                PRK: prk
                info: 'ARKG-KEM-HMAC-shared.' || DST_ext || ctx
                L: The length of k' in octets.
            c = t || c'
        s   ARKG-KEM-HMAC.Ns   ARKG-KEM-HMAC-mac.   s   ARKG-KEM-HMAC-shared.)
rw   r   r   r   rV   deriver   rZ   r[   r3   )r^   r   r   ry   ctx_subk_primec_primemkhmactr   r   s               r!   encapsz_KEM.encapsD  s    : $dl2S8..r3@@II!!DL036	
 

 &// 	 B	""GMMOOCRC ILL$t|3c9	
 

 &// 	
 K!tr    N)r   r   r   r   r   r   r1   r   r   r	   r   r   r   r   r    r!   r   r   
  s         	
NNN05 05L 0 0 0 04(/4;@	ue|	   44(4/44;@4	ue|	4 4 4 4 4 4r    r   c                   T    e Zd ZU dZeed<   eed<   dedededede	eef         f
d	Z
d
S )_ARKGz}
    ARKG instance parameters:
        BL        A key blinding scheme.
        KEM       A key encapsulation mechanism.
    blkempk_blpk_kemr   ry   r%   c                 Z   t          |          dk    rt          d          t          j        dt          |                    |z   }d|z   }d|z   }| j                            |||          \  }}	| j                            ||          }
| j                            ||
          }|	}||fS )a&  
        ARKG-Derive-Public-Key((pk_bl, pk_kem), ikm, ctx) -> (pk', kh)
            ARKG instance parameters:
                BL        A key blinding scheme.
                KEM       A key encapsulation mechanism.

            Inputs:
                pk_bl     A key blinding public key.
                pk_kem    A key encapsulation public key.
                ikm       Input entropy for KEM encapsulation.
                ctx       An octet string of length at most 64,
                            containing optional context and
                            application specific information
                            (can be a zero-length string).

            Output:
                pk'       A blinded public key.
                kh        A key handle for deriving the blinded
                            private key sk' corresponding to pk'.

            The output (pk', kh) is calculated as follows:

            if LEN(ctx) > 64:
                Abort with an error.

            ctx'    = I2OSP(LEN(ctx), 1) || ctx
            ctx_bl  = 'ARKG-Derive-Key-BL.'  || ctx'
            ctx_kem = 'ARKG-Derive-Key-KEM.' || ctx'

            (ikm_tau, c) = KEM-Encaps(pk_kem, ikm, ctx_kem)
            tau = BL-PRF(ikm_tau, ctx_bl)
            pk' = BL-Blind-Public-Key(pk_bl, tau)

            kh = c
        @   z,Context too long, should be at most 64 bytesrT   s   ARKG-Derive-Key-BL.s   ARKG-Derive-Key-KEM.)	r3   r)   rW   rX   r   r   r   r   r   )r^   r   r   r   ry   	ctx_primectx_blctx_kemrx   r   r   r   khs                r!   derive_public_keyz_ARKG.derive_public_key  s    T s88b==KLLLKc#hh//#5	')3)I5X__VS'::
gkk'6**7++E377|r    N)r   r   r   r   ru   r   r   r	   r1   r   r   r   r    r!   r   r   {  s           	GGG	III7%7 '7 	7
 7 
%u,	-7 7 7 7 7 7r    r   )&rW   dataclassesr   typingr   r   ,cryptography.hazmat.primitives.asymmetric.ecr   r   r   r	   r
   r   %cryptography.hazmat.primitives.hashesr   r   #cryptography.hazmat.primitives.hmacr   'cryptography.hazmat.primitives.kdf.hkdfr   ,cryptography.hazmat.primitives.serializationr   r   utilsr   r   r#   dictstrr   r*   r1   r4   rK   rM   ru   r   r   r   r    r!   <module>r      s  8  ! ! ! ! ! ! " " " " " " " "                F E E E E E E E 4 4 4 4 4 4 8 8 8 8 8 8 O O O O O O O O       $        P
L  *tC%&   =] =| = = = =5u 5 55 5 5 5 5EE$:EE E E E2 r r r r r r r rj #% #% #% #% #% #% #% #%L m m m m m m m m` A A A A A A A A A Ar    