Closed david-bakin-sl closed 1 month ago
Per @netopyr:
We will introduce a new interface,
SignatureVerifier
, which will have the Singleton-Scope. To make it available, we will introduce anAppContext
, which is given to all services during initialization. Most services will ignore it, but the Smart Contract Service keeps the reference to theSignatureVerifier
, which contains the required functionality.We decided to split counting the primitive keys and validate the signature. This will allow calculating the fees and checking them before calling
isSigned()
.The method
isSigned()
has an optional parameterverificationAssistant
to influence the signature verification. The method will iterate through the Key-tree and call theverificationAssistant
for each primitive key it encounters. If the response isVALID
orINVALID
, it will use the response. If the response isDELEGATE_TO_CRYPTOGRAPHIC_SIGNATURES
, it does the regular check.
(My comment: The optional verificationAssistant
will allow smart contracts to handle contract ID keys.)
// This interface will be provided to all services during initialization
interface AppContext {
SignatureVerifier signatureVerifier()
}
interface SignatureVerifier {
KeyCount countKeys(Key key);
boolean isSigned(Key key, Bytes message, SignatureMap signatureMap, @Nullable VerificationAssistant verificationAssistant);
}
record KeyCount(int numEcdsaKeys, int numEddsaKeys);
interface VerificationAssistant {
/**
* Given a key that is not a KeyList or ThresholdKey, returns a decision of how to verify its signature.
*/
VerificationDecision decideFor(Key simpleKey);
}
enum VerificationDecision { VALID, INVALID, DELEGATE_TO_CRYPTOGRAPHIC_SIGNATURES }
There needs to be a proper way for smart contracts service to get access to the app's ability to verify an arbitrary set of signatures, given an account, the data, and the signatures. Currently no service has the ability to do that - the only thing exposed is the list of verified signatures (that signed the transaction). But
isAuthorized{Raw}
requires it. (IsAuthorized
requires it for accounts with keys of arbitrary complexity and cryptography type,isAuthorizedRaw
only for accounts with a single "simple" key.)isAuthorized
takes a protobuf containing (arbitrarily many) signature pairs (public key "prefix" and the signature bytes), as well as an account and the message (hash). (HIP-632 link for 'isAuthorized`)Currently
isAuthorizedRaw
does it by directly using a platformCryptography
crypto engine, but:isAuthorized
there's the need to grok complex keysA fee calculator (or something) needs to be part of the API because the signature verification - encapsulated in the app service - has a wide range of cost (keys can be very complex) that the system contract will need to charge.
(Additionally, before a new fee schedule is available we should get a much closer estimate of gas costs for signature verification - but perhaps this should be a separate ticket.)
This is a prerequisite for implementing
isAuthorized
in the smart contracts service.