Time-bound asymmetric authentication proofs for offline, OTP-style, transaction-signing, duress-aware, and multi-device authentication flows.
PulseProof Sentinel Protocol, abbreviated PPS, is an experimental authentication protocol that replaces shared-secret TOTP-style codes with signed, time-bound, asymmetric proofs called Pulses.
Instead of sharing a secret between client and server, the user’s device holds a private key. The server stores only the corresponding public key.
A Pulse can be bound to:
PPS is designed to be implementable across many technologies, including PHP, JavaScript, TypeScript, Python, Go, Rust, Java, Swift, Kotlin, and constrained embedded environments.
PulseProof Sentinel is not intended to replace WebAuthn/FIDO2.
WebAuthn/FIDO2 is an excellent protocol for browser-based, origin-bound, phishing-resistant authentication. Where a full WebAuthn ceremony is available, it is usually the preferred choice.
PPS targets operational gaps where WebAuthn is unavailable, insufficient, or difficult to deploy:
In short:
WebAuthn is ideal for browser passkeys.
PPS is designed for OTP-like, offline, terminal, transaction, and constrained-device flows.
Traditional TOTP has several limitations:
TOTP = HMAC(shared_secret, time)
The server knows the shared secret. If the server database is compromised, OTP secrets may be exposed.
PPS changes the model:
Pulse = Sign(private_key, time + rp + nonce + counter + context + policy)
The server verifies using a public key.
This gives PPS several advantages:
Each authentication event produces a signed Pulse.
The verifier stores only public keys.
PPS can generate and verify Pulses without requiring a live network round-trip, although nonce-based online mode is recommended when possible.
PPS can produce human-visible Trust Codes for legacy OTP-style input flows.
However, the full Pulse Token is strongly preferred over manual code entry.
For transaction signing, PPS can embed a two-digit amount checksum into the Trust Code.
Example:
Amount: 2,500,067 IRR
Trust Code: 49371867
The last two digits, 67, are derived from the transaction amount.
This helps users detect transaction tampering.
PPS supports an optional duress key.
If a user authenticates under coercion, the device can sign with a hidden duress key.
The server can return a normal-looking success response while internally:
The attacker should not be able to distinguish a duress authentication from a normal one.
PPS supports optional offline multi-device approval.
Example:
Phone signs transaction
Watch signs transaction
Server requires both signatures
This is useful for high-value fintech, banking, crypto withdrawal, and administrative approval flows.
The server can issue a policy object:
{
"min_trust_digits": 8,
"require_biometric": true,
"require_secure_enclave": true,
"threshold": 2,
"max_amount_minor": 10000000,
"require_proximity": true
}
The Pulse is cryptographically bound to the policy hash.
A Pulse can be bound to context such as:
This can increase resistance to relay and phishing attacks.
| Capability | SMS OTP | TOTP | Push 2FA | Challenge-Response OTP | WebAuthn / FIDO2 | PulseProof Sentinel |
|---|---|---|---|---|---|---|
| Server stores shared secret | Usually | Yes | Usually | Sometimes | No | No |
| Primary proof | Possession of SIM | HMAC shared secret | Proprietary app/server channel | HMAC or asymmetric challenge | Public-key signature | Public-key signature |
| Offline capable | No | Yes | No | Sometimes | Limited | Yes |
| Works with legacy OTP input fields | Yes | Yes | No | Sometimes | No | Yes |
| Phishing resistance | Low | Low | Medium | Medium | High | High when full Pulse Token is used |
| Replay protection | Weak | Time-window based | Server-controlled | Challenge-based | Strong | Strong |
| Transaction amount confirmation | No | No | Sometimes | Rare | Possible with payment extensions | Yes, with AmountMark |
| Silent duress support | No | No | Rare | No | No standard mechanism | Optional |
| Offline multi-device threshold approval | No | No | No | No | Limited | Optional |
| Suitable for constrained terminals | Low | High | Low | Medium | Low | High |
| Suitable for browser passkey flows | No | No | No | No | Excellent | Possible, but WebAuthn preferred |
| Open wire format | No | RFC 6238 | Usually proprietary | Varies | W3C standard | Yes |
PPS is not claiming to be better than WebAuthn for browser authentication.
WebAuthn is preferred when:
PPS is designed for cases where WebAuthn is not enough or not practical.
A simplified PPS flow:
1. Relying Party creates a challenge
- nonce
- rp_id
- optional transaction hash
- optional policy object
2. Authenticator receives challenge
- via QR code, deep link, SDK, or manual context
3. Authenticator signs a Pulse
- time epoch
- rp_id hash
- nonce
- counter
- policy hash
- context hash
- next public key, if ratcheting
4. Authenticator displays optional Trust Code / AmountMark
5. Relying Party verifies:
- signature
- rp binding
- nonce
- epoch
- expiration
- counter
- policy
- context
- amount mark
- rotation state
6. Authentication or transaction approval succeeds
Website:
Sign in to example.com
Scan this QR code with your PPS authenticator.
Authenticator app:
Login request
Service: example.com
Device: Phone
Risk: Normal
Trust Code: 493718
Trust Phrase: river bronze lantern
[Reject] [Approve]
Authenticator app:
Withdrawal request
Amount: 2,500,067 IRR
To: IR820540102680020817909002
Service: example.com
Trust Code: 49371867
[Reject] [Approve Withdrawal]
The last two digits of the Trust Code match the last two digits of the amount.
| Module | Description | Status |
|---|---|---|
| Core Pulse | Ed25519-signed time-bound authentication proof | Specified |
| Verifiable Ratchet | Forward-secure key rotation using signed next public key | Specified |
| Silent Duress | Hidden duress key producing Honey-Pulse | Specified |
| Threshold Mode | Offline n-of-m multisig approval | Specified |
| Context Binding | Bind Pulse to session, transaction, BLE, acoustic, or device context | Specified |
| Policy Binding | Bind Pulse to dynamic server policy | Specified |
| AmountMark | Embed transaction amount checksum into Trust Code | Specified |
| Trust Phrase | Optional human-friendly word phrase | Specified |
The mandatory profile for PPS version 1 is:
PPS-ED25519-CBOR30
It uses:
| Component | Value |
|---|---|
| Signature algorithm | Ed25519 |
| Hash algorithm | SHA-256 |
| KDF | HKDF-SHA256 |
| Canonical encoding | Deterministic CBOR |
| Text encoding | base64url without padding |
| Default epoch length | 30 seconds |
Optional post-quantum and hybrid profiles may be defined in future revisions.
PPS is currently an experimental specification.
Reference implementations are planned or in progress.
| Language | Package / Directory | Status |
|---|---|---|
| PHP | pps-php |
Planned |
| JavaScript | pps-js |
Planned |
| Python | pps-python |
Planned |
| Go | pps-go |
Planned |
| Rust | pps-rust |
Planned |
Implementers should not use PPS in production without independent security review.
Implementations should use well-reviewed cryptographic libraries.
ext-sodium
paragonie/sodium_compat
spomky-labs/cbor-php
ext-gmp
@noble/ed25519
@noble/hashes
cbor-x
Web Crypto API where appropriate
cryptography
cbor2
crypto/ed25519
fxamacker/cbor
ed25519-dalek
sha2
hkdf
ciborium
Do not implement Ed25519, HKDF, SHA-256, or CBOR from scratch unless absolutely necessary.
This repository currently contains or will contain:
.
├── README.md
├── SPEC.md
├── SECURITY.md
├── LICENSE
├── CONTRIBUTING.md
├── CODE_OF_CONDUCT.md
├── CHANGELOG.md
├── docs/
│ ├── overview.md
│ ├── comparison.md
│ ├── threat-model.md
│ ├── implementers-guide.md
│ ├── faq.md
│ └── ietf.md
├── cddl/
│ └── pps.cddl
├── examples/
│ ├── php/
│ ├── js/
│ └── python/
├── test-vectors/
│ └── README.md
└── interop/
└── README.md
If you want to implement PPS:
SPEC.md.For high-security deployments, prefer full Pulse Token transmission over manual Trust Code entry.
PPS is experimental.
It has not been independently audited.
Do not use it in production systems without:
PPS is designed to improve security against:
PPS does not magically prevent:
Security depends on implementation and deployment.
PulseProof Sentinel builds on many existing ideas and standards, including:
PPS does not claim that these individual mechanisms are new.
Its contribution is an interoperable protocol profile that combines them into a compact, technology-agnostic wire format for offline, OTP-like, transaction-signing, duress-aware, and threshold authentication flows.
PPS is submitted as an individual Internet-Draft:
draft-hezami-pulseproof-sentinel
Datatracker:
https://datatracker.ietf.org/doc/draft-hezami-pulseproof-sentinel/
Feedback is welcome, especially on:
Contributions are welcome.
Please read:
For security vulnerabilities, do not open a public issue. Please follow the private reporting process described in SECURITY.md.
Unless otherwise noted:
See LICENSE for details.
“PulseProof Sentinel” is the name of this protocol project.
This project is independent and is not affiliated with any existing product or service using a similar name.
If you believe there is a naming conflict, please open an issue or contact the maintainers.
This protocol is experimental and provided as-is.
Use at your own risk.