WebAuthn256r1
A library to verify ECDSA signature though WebAuthn on the secp256r1 curve
Functions
generateMessage
Validate the webauthn data and generate the signature message needed to recover
1. The signature counter is not checked in this implementation because
we already have the nonce on-chain to prevent the anti-replay attack.
The counter is 4-bytes long and it is located at bytes 33 of the authenticator data.
2. The RP.ID is not checked in this implementation as it is impossible to generate
the same keys for different RP.IDs with a well formed authenticator. The hash of the id
is 32-bytes long and it is located at bytes 0 of the authenticator data.
3. The length of the authenticator data is not fixed. It is at least 37 bytes
(rpIdHash (32) + flags (1) + counter (4)) but it can be longer if there is an
attested credential data and/or some extensions data. As we do not consider
the counter in this implementation, we only require the authenticator data to be
at least 32 bytes long in order to save some calldata gas.
4. You may probably ask why we encode the challenge in base64 on-chain instead of
of sending it already encoded to save some gas. This library is opinionated and
it assumes that it is used in the context of Account Abstraction. In this context,
valuable informations required to proceed the transaction will be stored in the
challenge meaning we need the challenge in clear to use it later in the flow.
That's why we decided to add an extra encoding step during the validation.
5. It is assumed this is not the responsibility of this contract to check the value
of the alg
parameter. It is expected this contract will be extended by another
contract that will redirect the message produced by this contract to the right
recovery function.
6. Both extension data and attested credential data are out of scope of this implementation.
7. It is not the responsibility of this contract to validate the attestation statement formats
This contract is based on the level 2 of the WebAuthn specification.
and until proven otherwise compliant with the level 3 of the specification.
function generateMessage(
bytes calldata authenticatorData,
bytes calldata clientData,
bytes calldata clientChallenge
)
internal
pure
returns (bytes32 message);
Parameters
Name | Type | Description |
---|---|---|
authenticatorData | bytes | The authenticator data structure encodes contextual bindings made by the authenticator. Described here: https://www.w3.org/TR/webauthn-2/#authenticator-data |
clientData | bytes | This is the client data that was signed. The client data represents the contextual bindings of both the WebAuthn Relying Party and the client. Described here: https://www.w3.org/TR/webauthn-2/#client-data |
clientChallenge | bytes | This is the challenge that was sent to the client to sign. It is part of the client data. In a classic non-EVM flow, this challenge is generated by the server and sent to the client to avoid replay attack. In our context, as we already have the nonce for this purpose we use this field to pass the arbitrary execution order. This value is expected to not be encoded in Base64, the encoding is done during the verification. |
Returns
Name | Type | Description |
---|---|---|
message | bytes32 | The signature message needed to recover |
verify
Verify ECDSA signature though WebAuthn on the secp256r1 curve
function verify(
bytes calldata authData,
bytes calldata clientData,
bytes calldata clientChallenge,
uint256 r,
uint256 s,
uint256 qx,
uint256 qy
)
internal
returns (bool);
Errors
InvalidAuthenticatorData
error InvalidAuthenticatorData();
InvalidClientData
error InvalidClientData();
InvalidChallenge
error InvalidChallenge();