pulseproof-sentinel

PulseProof Sentinel Protocol

Time-bound asymmetric authentication proofs for offline, OTP-style, transaction-signing, duress-aware, and multi-device authentication flows.

IETF Internet-Draft Protocol Version 1 Status: Experimental License: Apache-2.0


What is PulseProof Sentinel?

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.


Important Positioning

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.

Why PPS?

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:


Feature Highlights

1. Asymmetric Time-Bound Pulses

Each authentication event produces a signed Pulse.

The verifier stores only public keys.

2. Offline Capability

PPS can generate and verify Pulses without requiring a live network round-trip, although nonce-based online mode is recommended when possible.

3. OTP-Compatible UX

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.

4. Transaction AmountMark

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.

5. Silent Duress / Honey-Pulse

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.

6. Offline Threshold Co-Signing

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.

7. Dynamic Policy Binding

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.

8. Environmental Context Binding

A Pulse can be bound to context such as:

This can increase resistance to relay and phishing attacks.


Comparison With Other 2FA Methods

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

Important Note

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.


How PPS Works

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

Example User Experience

Login

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]

Transaction Signing

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.


Protocol Modules

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

Mandatory Cryptographic Profile

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.


Implementation Status

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.

PHP

ext-sodium
paragonie/sodium_compat
spomky-labs/cbor-php
ext-gmp

JavaScript / TypeScript

@noble/ed25519
@noble/hashes
cbor-x
Web Crypto API where appropriate

Python

cryptography
cbor2

Go

crypto/ed25519
fxamacker/cbor

Rust

ed25519-dalek
sha2
hkdf
ciborium

Do not implement Ed25519, HKDF, SHA-256, or CBOR from scratch unless absolutely necessary.


Repository Structure

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

Getting Started

If you want to implement PPS:

  1. Read SPEC.md.
  2. Implement deterministic CBOR encoding.
  3. Implement Ed25519 signing and verification.
  4. Implement HKDF-based Trust Code derivation.
  5. Implement nonce, epoch, counter, and expiration validation.
  6. Implement policy and context hash verification.
  7. Add rate limiting and secure key storage.
  8. Test against published test vectors.

For high-security deployments, prefer full Pulse Token transmission over manual Trust Code entry.


Security Status

PPS is experimental.

It has not been independently audited.

Do not use it in production systems without:


Threat Model Summary

PPS is designed to improve security against:

PPS does not magically prevent:

Security depends on implementation and deployment.


Prior Art

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.


IETF Internet-Draft

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:


Contributing

Contributions are welcome.

Please read:

For security vulnerabilities, do not open a public issue. Please follow the private reporting process described in SECURITY.md.


License

Unless otherwise noted:

See LICENSE for details.


Trademark and Naming Notice

“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.


Disclaimer

This protocol is experimental and provided as-is.

Use at your own risk.