Skip to content

WIP: SecpPrivKeySegment impl for FFM - #482

Draft
msgilligan wants to merge 2 commits into
masterfrom
msgilligan/secp-ffm-segment-impl
Draft

WIP: SecpPrivKeySegment impl for FFM#482
msgilligan wants to merge 2 commits into
masterfrom
msgilligan/secp-ffm-segment-impl

Conversation

@msgilligan

Copy link
Copy Markdown
Member

No description provided.

@msgilligan
msgilligan force-pushed the msgilligan/secp-ffm-segment-impl branch from 8debe20 to 05b8881 Compare July 29, 2026 02:06
@msgilligan
msgilligan requested a review from liamgilligan July 29, 2026 03:42
@msgilligan

Copy link
Copy Markdown
Member Author

Commits 1-4 can be rebased and squashed after PR #483 is merged.

Add SecpPrivKeySegment, an implementation of SecpPrivKey that keeps
the data in an owned Auto memory segment. This segment will be disposed
by Java GC after the SecpPrivKeySegment wrapper class is unreachable.
The segment() method will return a read-only segment that can be directly
passed to secp256k1 foreign functions.

In the FFM implementation of ecPrivKeyCreate() create and
return a SecpPrivKeySegment rather than the generic SecpPrivKeyImpl. 
The privKeySeg() method will return the read-only, pre-existing segment if
a SecpPrivKeySegment is passed or create a temporary, writable segment
if another SecpPrivKey is passed. zeroIfTemp() will zero the temporary
segments.
This is an experimental, partial implementation backed by
a MemorySegment in internal libsecp256k1 format. It's not clear
to me yet what the most efficient format to use is, should it
be the internal format, serialized uncompressed (65 bytes), or
as two 32 byte fields. I suppose it depends upon which conversions
are most common.

For this implementation .segment() returns a ready-to-use segment
for most native pubKey operations, but conversions are required
for the other getters.
@msgilligan
msgilligan force-pushed the msgilligan/secp-ffm-segment-impl branch from 05b8881 to 98b61de Compare July 30, 2026 00:13
@msgilligan

Copy link
Copy Markdown
Member Author

This should be rebased after PR #506 is merged.

@msgilligan
msgilligan requested a review from liamgilligan August 9, 2026 00:05

@liamgilligan liamgilligan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I assume that we are relying on the secp instance to validate the priv/pubkey segments used by the constructors -- is this a good decision?

return "Secp256k1/" + ProviderId.LIBSECP256K1_FFM;
}

/// Fill temporary segments with zeros. In this context, non-temporary segments are read-only

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this comment can be a little more clear. Perhaps it should be stated that generally non-temporary segments are from the Secp*Segment objects and temporary segments are all others.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the method should be named zeroIfWritable? It's a low-level helper method and it doesn't really know what is temporary or not -- it just zeros MemorySegments that are writable. We could then document how it used elsewhere.


@Override
public void destroy() {
// TODO: Make sure the zeroing is not optimized out by the compiler or JIT

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the C equivalent.

I believe this may work:

private static final VarHandle BYTE_VH = ValueLayout.JAVA_BYTE.varHandle();
public void destroy() {
    if (destroyed) return;
    for (long i = 0, n = segment.byteSize(); i < n; i++) {
        BYTE_VH.setVolatile(segment, i, (byte) 0);
    }
    destroyed = true;
}

This basically allows for volatile writes to off-heap memory, which shouldn't be optimized away.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's in interesting idea. I think we should find out whether the JDK/FFM can optimize out a call to fill() and if we need to do what you are suggesting, we'll do it.

@msgilligan

Copy link
Copy Markdown
Member Author

Looks good. I assume that we are relying on the secp instance to validate the priv/pubkey segments used by the constructors -- is this a good decision?

At the very least should document in the constructors that we are assuming valid data. Since these are internal classes I think it is ok to make (and document) that assumption if we can be sure it always holds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants